blinker-sdk 1.0.1 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +226 -147
- package/dist/blinker.min.js +452 -1
- package/dist/capture/deduplication.d.ts +26 -0
- package/dist/capture/deduplication.d.ts.map +1 -0
- package/dist/capture/errorHandler.d.ts +5 -0
- package/dist/capture/errorHandler.d.ts.map +1 -0
- package/dist/capture/index.d.ts +4 -0
- package/dist/capture/index.d.ts.map +1 -0
- package/dist/capture/types.d.ts +13 -0
- package/dist/capture/types.d.ts.map +1 -0
- package/dist/context/SessionManager.d.ts +16 -0
- package/dist/context/SessionManager.d.ts.map +1 -0
- package/dist/context/UserContext.d.ts +19 -0
- package/dist/context/UserContext.d.ts.map +1 -0
- package/dist/context/index.d.ts +4 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/types.d.ts +18 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/core/Blinker.d.ts +45 -0
- package/dist/core/Blinker.d.ts.map +1 -0
- package/dist/core/config.d.ts +29 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/types.d.ts +54 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/filters/FilterEngine.d.ts +9 -0
- package/dist/filters/FilterEngine.d.ts.map +1 -0
- package/dist/filters/defaults.d.ts +3 -0
- package/dist/filters/defaults.d.ts.map +1 -0
- package/dist/filters/index.d.ts +4 -0
- package/dist/filters/index.d.ts.map +1 -0
- package/dist/filters/types.d.ts +8 -0
- package/dist/filters/types.d.ts.map +1 -0
- package/dist/index.cjs.js +2192 -266
- package/dist/index.d.ts +7 -32
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +2192 -266
- package/dist/queue/EventQueue.d.ts +21 -0
- package/dist/queue/EventQueue.d.ts.map +1 -0
- package/dist/queue/index.d.ts +4 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/storage.d.ts +16 -0
- package/dist/queue/storage.d.ts.map +1 -0
- package/dist/queue/types.d.ts +21 -0
- package/dist/queue/types.d.ts.map +1 -0
- package/dist/sampling/RateLimiter.d.ts +12 -0
- package/dist/sampling/RateLimiter.d.ts.map +1 -0
- package/dist/sampling/Sampler.d.ts +16 -0
- package/dist/sampling/Sampler.d.ts.map +1 -0
- package/dist/sampling/index.d.ts +4 -0
- package/dist/sampling/index.d.ts.map +1 -0
- package/dist/sampling/types.d.ts +10 -0
- package/dist/sampling/types.d.ts.map +1 -0
- package/dist/transport/index.d.ts +3 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/sender.d.ts +4 -0
- package/dist/transport/sender.d.ts.map +1 -0
- package/dist/transport/types.d.ts +12 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/utils/browser.d.ts +10 -0
- package/dist/utils/browser.d.ts.map +1 -0
- package/dist/utils/hash.d.ts +4 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/widget/Avatar.d.ts +20 -0
- package/dist/widget/Avatar.d.ts.map +1 -0
- package/dist/widget/Dialog.d.ts +25 -0
- package/dist/widget/Dialog.d.ts.map +1 -0
- package/dist/widget/QuestionEngine.d.ts +7 -0
- package/dist/widget/QuestionEngine.d.ts.map +1 -0
- package/dist/widget/Widget.d.ts +28 -0
- package/dist/widget/Widget.d.ts.map +1 -0
- package/dist/widget/index.d.ts +8 -0
- package/dist/widget/index.d.ts.map +1 -0
- package/dist/widget/styles.d.ts +5 -0
- package/dist/widget/styles.d.ts.map +1 -0
- package/dist/widget/types.d.ts +46 -0
- package/dist/widget/types.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/Blinker.d.ts +0 -65
- package/dist/Blinker.d.ts.map +0 -1
- package/dist/errorHandler.d.ts +0 -19
- package/dist/errorHandler.d.ts.map +0 -1
- package/dist/sender.d.ts +0 -11
- package/dist/sender.d.ts.map +0 -1
- package/dist/types.d.ts +0 -92
- package/dist/types.d.ts.map +0 -1
package/dist/blinker.min.js
CHANGED
|
@@ -1 +1,452 @@
|
|
|
1
|
-
"use strict";var BlinkerSDK=(()=>{var
|
|
1
|
+
"use strict";var BlinkerSDK=(()=>{var B=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var ue=Object.getOwnPropertyNames;var ce=Object.prototype.hasOwnProperty;var ge=(r,e)=>{for(var t in e)B(r,t,{get:e[t],enumerable:!0})},he=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ue(e))!ce.call(r,n)&&n!==t&&B(r,n,{get:()=>e[n],enumerable:!(i=de(e,n))||i.enumerable});return r};var pe=r=>he(B({},"__esModule",{value:!0}),r);var Se={};ge(Se,{Blinker:()=>m,DEFAULT_FILTERS:()=>p,DEFAULT_WIDGET_CONFIG:()=>W,SDK_VERSION:()=>w,blinker:()=>ae,default:()=>xe});var fe="https://api.blinker.live",w="2.0.1",E={EVENT_QUEUE:"blinker_event_queue",SESSION:"blinker_session",USER_CONTEXT:"blinker_user_context"},g={endpoint:fe,enabled:!0,captureErrors:!0,captureRejections:!0,enableBatching:!0,batchSize:10,flushInterval:5e3,enableOfflineStorage:!0,maxStoredEvents:100,enableDeduplication:!0,deduplicationWindow:6e4,maxEventsPerMinute:100,sampleRate:1,debug:!1},x={OFFLINE_RETRY_TIMEOUT:3e4,MIN_FLUSH_INTERVAL:1e3,MAX_FLUSH_INTERVAL:6e4};var p={ignoreHttpCodes:[401,403],ignoreErrorTypes:[],ignoreMessagePatterns:["ResizeObserver loop","Script error","ResizeObserver loop completed"],captureAll:!1};var P="[Blinker]";function U(r){let e=()=>{};return r?{log:(...t)=>console.log(P,...t),warn:(...t)=>console.warn(P,...t),error:(...t)=>console.error(P,...t)}:{log:e,warn:e,error:e}}var Q=U(!1);function C(r){Q=U(r)}function d(){return Q}var T=class{constructor(e){var t,i,n,s;this.filters={ignoreHttpCodes:(t=e==null?void 0:e.ignoreHttpCodes)!=null?t:p.ignoreHttpCodes,ignoreErrorTypes:(i=e==null?void 0:e.ignoreErrorTypes)!=null?i:p.ignoreErrorTypes,ignoreMessagePatterns:(n=e==null?void 0:e.ignoreMessagePatterns)!=null?n:p.ignoreMessagePatterns,captureAll:(s=e==null?void 0:e.captureAll)!=null?s:p.captureAll}}shouldCapture(e,t,i){let n=d();if(this.filters.captureAll)return!0;if(i!==void 0&&this.filters.ignoreHttpCodes.includes(i))return n.log("Event filtered out by HTTP code:",i),!1;if(t&&this.filters.ignoreErrorTypes.includes(t))return n.log("Event filtered out by error type:",t),!1;for(let s of this.filters.ignoreMessagePatterns)if(e.toLowerCase().includes(s.toLowerCase()))return n.log("Event filtered out by message pattern:",s),!1;if(i===void 0){let s=e.match(/(?:HTTP\s*|status[:\s]*)?(\d{3})(?:\s|$|:)/i);if(s){let o=parseInt(s[1],10);if(o>=100&&o<600&&this.filters.ignoreHttpCodes.includes(o))return n.log("Event filtered out by extracted HTTP code:",o),!1}}return!0}getFilters(){return{...this.filters}}updateFilters(e){var t,i,n,s;this.filters={ignoreHttpCodes:(t=e.ignoreHttpCodes)!=null?t:this.filters.ignoreHttpCodes,ignoreErrorTypes:(i=e.ignoreErrorTypes)!=null?i:this.filters.ignoreErrorTypes,ignoreMessagePatterns:(n=e.ignoreMessagePatterns)!=null?n:this.filters.ignoreMessagePatterns,captureAll:(s=e.captureAll)!=null?s:this.filters.captureAll}}};function h(){return typeof window!="undefined"}function N(){if(!h())return!1;try{let r="__blinker_test__";return localStorage.setItem(r,"test"),localStorage.removeItem(r),!0}catch(r){return!1}}function H(){if(!h())return!1;try{let r="__blinker_test__";return sessionStorage.setItem(r,"test"),sessionStorage.removeItem(r),!0}catch(r){return!1}}function f(){var r;return h()&&(r=navigator.onLine)!=null?r:!0}function V(){if(h())return window.location.href}function G(){return h()?window.location.pathname:"unknown"}function j(){if(h())return navigator.userAgent}function K(){if(h())return document.referrer||void 0}var I=class{constructor(e=100){this.storageKey=E.EVENT_QUEUE;this.maxEvents=e,this.available=N()}isAvailable(){return this.available}store(e){if(!this.available)return!1;let t=d();try{let i=this.getAll(),n={event:e,storedAt:new Date().toISOString(),retries:0};for(i.push(n);i.length>this.maxEvents;)i.shift();return localStorage.setItem(this.storageKey,JSON.stringify(i)),t.log(`Event stored offline. Total stored: ${i.length}`),!0}catch(i){return t.error("Failed to store event offline:",i),!1}}storeMany(e){if(!this.available||e.length===0)return 0;let t=d(),i=0;try{let n=this.getAll();for(let s of e){let o={event:s,storedAt:new Date().toISOString(),retries:0};n.push(o),i++}for(;n.length>this.maxEvents;)n.shift();return localStorage.setItem(this.storageKey,JSON.stringify(n)),t.log(`Stored ${i} events offline. Total stored: ${n.length}`),i}catch(n){return t.error("Failed to store events offline:",n),i}}getAll(){if(!this.available)return[];try{let e=localStorage.getItem(this.storageKey);return e?JSON.parse(e):[]}catch(e){return[]}}retrieveAll(){if(!this.available)return[];let e=d();try{let t=this.getAll();return t.length===0?[]:(localStorage.removeItem(this.storageKey),e.log(`Retrieved ${t.length} stored events`),t.map(i=>i.event))}catch(t){return e.error("Failed to retrieve stored events:",t),[]}}count(){return this.getAll().length}clear(){if(this.available)try{localStorage.removeItem(this.storageKey)}catch(e){}}};async function J(r,e,t){let i=d(),n=`${r.replace(/\/$/,"")}/events`;if(t.length===0)return{success:!0,count:0};let s=async()=>{try{let a=t.length===1?Y(t[0]):{events:t.map(Y)},l=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json","x-blinker-token":e},body:JSON.stringify(a)});if(!l.ok){let u=await l.text().catch(()=>"Unknown error");return i.error(`Failed to send events: ${l.status} - ${u}`),{success:!1,error:`HTTP ${l.status}: ${u}`}}return i.log(`Events sent successfully: ${t.length} event(s)`),{success:!0,count:t.length}}catch(a){let l=a instanceof Error?a.message:"Unknown error";return i.error("Error sending events:",l),{success:!1,error:l}}},o=await s();return!o.success&&h()&&!f()&&(i.log("Offline, waiting for connection to retry..."),await me(x.OFFLINE_RETRY_TIMEOUT))?(i.log("Back online, retrying..."),s()):o}function Y(r){return{type:r.type,message:r.message,payload:r.payload||{},timestamp:r.timestamp,url:r.url,userAgent:r.userAgent,sessionId:r.sessionId,userId:r.userId,userTraits:r.userTraits,context:r.context,count:r.count}}function me(r){return new Promise(e=>{if(!h()){e(!1);return}let t=setTimeout(()=>e(!1),r),i=()=>{clearTimeout(t),window.removeEventListener("online",i),e(!0)};window.addEventListener("online",i)})}var L=class{constructor(e,t){this.queue=[];this.flushTimer=null;this.isFlushing=!1;this.handleOnline=()=>{d().log("Back online, flushing stored events"),this.flush()};var i,n,s,o,a,l;this.token=e,this.config={endpoint:(i=t==null?void 0:t.endpoint)!=null?i:g.endpoint,enableBatching:(n=t==null?void 0:t.enableBatching)!=null?n:g.enableBatching,batchSize:(s=t==null?void 0:t.batchSize)!=null?s:g.batchSize,flushInterval:Math.max(x.MIN_FLUSH_INTERVAL,Math.min((o=t==null?void 0:t.flushInterval)!=null?o:g.flushInterval,x.MAX_FLUSH_INTERVAL)),enableOfflineStorage:(a=t==null?void 0:t.enableOfflineStorage)!=null?a:g.enableOfflineStorage,maxStoredEvents:(l=t==null?void 0:t.maxStoredEvents)!=null?l:g.maxStoredEvents,onError:t==null?void 0:t.onError},this.storage=new I(this.config.maxStoredEvents),this.config.enableBatching&&this.startFlushTimer(),h()&&this.config.enableOfflineStorage&&window.addEventListener("online",this.handleOnline)}async add(e){let t=d();return this.config.enableBatching?(this.queue.push(e),t.log(`Event queued. Queue size: ${this.queue.length}`),this.queue.length>=this.config.batchSize?this.flush():{success:!0}):this.sendImmediately([e])}async flush(){let e=d();if(this.isFlushing)return e.log("Flush already in progress, skipping"),{success:!0};let t=[...this.queue];if(this.queue=[],this.config.enableOfflineStorage&&f()){let i=this.storage.retrieveAll();i.length>0&&(t.unshift(...i),e.log(`Including ${i.length} stored offline events`))}if(t.length===0)return{success:!0,count:0};this.isFlushing=!0;try{let i=await this.sendImmediately(t);return!i.success&&this.config.enableOfflineStorage&&!f()&&(e.log("Send failed while offline, storing events"),this.storage.storeMany(t)),i}finally{this.isFlushing=!1}}async sendImmediately(e){let t=d();if(!f()&&this.config.enableOfflineStorage)return t.log("Offline, storing events for later"),{success:!0,count:this.storage.storeMany(e)};let i=await J(this.config.endpoint,this.token,e);return!i.success&&this.config.onError&&this.config.onError(i.error||"Unknown error sending events"),i}getStats(){let e=this.queue.length,t=this.storage.count();return{queueSize:e,storedSize:t,totalPending:e+t}}size(){return this.queue.length}startFlushTimer(){this.flushTimer||(this.flushTimer=setInterval(()=>{this.queue.length>0&&this.flush()},this.config.flushInterval))}stopFlushTimer(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null)}destroy(){this.stopFlushTimer(),h()&&window.removeEventListener("online",this.handleOnline),this.queue.length>0&&f()?this.flush():this.queue.length>0&&this.config.enableOfflineStorage&&this.storage.storeMany(this.queue),this.queue=[]}};function be(r){let e=5381;for(let t=0;t<r.length;t++)e=(e<<5)+e^r.charCodeAt(t);return(e>>>0).toString(16)}function X(r,e){let t=r;if(e){let n=e.split(`
|
|
2
|
+
`).slice(1,4).map(s=>s.replace(/:\d+:\d+\)?$/,"").trim()).join("|");t+="|"+n}return be(t)}function v(){let r=Date.now().toString(36),e=Math.random().toString(36).substring(2,10);return`${r}-${e}`}var M=class{constructor(){this.session=null;this.storageKey=E.SESSION;this.storageAvailable=H(),this.initSession()}initSession(){let e=d();if(this.storageAvailable)try{let t=sessionStorage.getItem(this.storageKey);if(t){this.session=JSON.parse(t),e.log("Session restored:",this.session.id);return}}catch(t){}this.session={id:v(),startedAt:new Date().toISOString(),pageViews:0,lastActivityAt:new Date().toISOString()},this.persist(),e.log("New session created:",this.session.id)}getSessionId(){var e,t;return(t=(e=this.session)==null?void 0:e.id)!=null?t:v()}getSession(){return this.session||this.initSession(),{...this.session}}recordPageView(){this.session&&(this.session.pageViews++,this.session.lastActivityAt=new Date().toISOString(),this.persist())}touch(){this.session&&(this.session.lastActivityAt=new Date().toISOString(),this.persist())}getDuration(){if(!this.session)return 0;let e=new Date(this.session.startedAt).getTime();return Date.now()-e}persist(){if(!(!this.storageAvailable||!this.session))try{sessionStorage.setItem(this.storageKey,JSON.stringify(this.session))}catch(e){}}endSession(){if(this.storageAvailable)try{sessionStorage.removeItem(this.storageKey)}catch(e){}this.session=null}};var q=class{constructor(e){this.user=null;this.customContext={};this.sessionManager=e}identify(e,t){let i=d();this.user={userId:e,traits:t?{...t}:void 0,identifiedAt:new Date().toISOString()},i.log("User identified:",e)}getUserId(){var e;return(e=this.user)==null?void 0:e.userId}getUserTraits(){var e;return(e=this.user)!=null&&e.traits?{...this.user.traits}:void 0}isIdentified(){return this.user!==null}setContext(e,t){let i=d();this.customContext[e]=t,i.log("Context set:",e)}getContextValue(e){return this.customContext[e]}getCustomContext(){return{...this.customContext}}getEventContext(){var e,t;return{sessionId:this.sessionManager.getSessionId(),userId:(e=this.user)==null?void 0:e.userId,userTraits:(t=this.user)!=null&&t.traits?{...this.user.traits}:void 0,custom:{...this.customContext}}}clearIdentity(){let e=d();this.user=null,e.log("User identity cleared")}clearAll(){let e=d();this.user=null,this.customContext={},e.log("All context cleared")}};var Z=60*1e3,A=class{constructor(e){this.maxPerMinute=e!=null?e:g.maxEventsPerMinute,this.state={count:0,windowStart:Date.now(),dropped:0}}allow(){let e=d();if(this.maxPerMinute===0)return!0;let t=Date.now();return t-this.state.windowStart>=Z&&(this.state.dropped>0&&e.warn(`Rate limit: ${this.state.dropped} events dropped in last minute`),this.state={count:0,windowStart:t,dropped:0}),this.state.count<this.maxPerMinute?(this.state.count++,!0):(this.state.dropped++,this.state.dropped===1&&e.warn(`Rate limit reached: ${this.maxPerMinute} events/minute`),!1)}getState(){return{...this.state}}getRemaining(){return this.maxPerMinute===0?1/0:Date.now()-this.state.windowStart>=Z?this.maxPerMinute:Math.max(0,this.maxPerMinute-this.state.count)}reset(){this.state={count:0,windowStart:Date.now(),dropped:0}}setLimit(e){this.maxPerMinute=e}};var R=class{constructor(e){this.sampled=0;this.dropped=0;this.sampleRate=Math.max(0,Math.min(1,e!=null?e:g.sampleRate))}shouldSample(e=!1){let t=d();return e?(this.sampled++,!0):this.sampleRate>=1?(this.sampled++,!0):this.sampleRate<=0?(this.dropped++,!1):Math.random()<this.sampleRate?(this.sampled++,!0):(this.dropped++,t.log("Event sampled out"),!1)}getStats(){return{sampled:this.sampled,dropped:this.dropped,rate:this.sampleRate}}setRate(e){this.sampleRate=Math.max(0,Math.min(1,e))}getRate(){return this.sampleRate}resetStats(){this.sampled=0,this.dropped=0}};var $=class{constructor(e,t){this.entries=new Map;this.cleanupTimer=null;this.enabled=e!=null?e:g.enableDeduplication,this.windowMs=t!=null?t:g.deduplicationWindow,this.enabled&&this.startCleanup()}check(e,t){let i=X(e,t);if(!this.enabled)return{shouldSend:!0,fingerprint:i,count:1,isDuplicate:!1};let n=d(),s=Date.now(),o=this.entries.get(i);if(o){if(s-o.firstSeen<this.windowMs)return o.count++,o.lastSeen=s,n.log(`Duplicate error detected (count: ${o.count}):`,e.substring(0,50)),{shouldSend:!1,fingerprint:i,count:o.count,isDuplicate:!0};this.entries.delete(i)}return this.entries.set(i,{fingerprint:i,firstSeen:s,count:1,lastSeen:s}),{shouldSend:!0,fingerprint:i,count:1,isDuplicate:!1}}getCount(e){var t,i;return(i=(t=this.entries.get(e))==null?void 0:t.count)!=null?i:1}flush(){let e=Array.from(this.entries.values()).filter(t=>t.count>1);return this.entries.clear(),e}startCleanup(){this.cleanupTimer=setInterval(()=>{this.cleanup()},this.windowMs)}cleanup(){let e=Date.now(),t=d(),i=0;for(let[n,s]of this.entries)e-s.firstSeen>=this.windowMs&&(this.entries.delete(n),i++);i>0&&t.log(`Deduplication cleanup: removed ${i} expired entries`)}destroy(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),this.cleanupTimer=null),this.entries.clear()}getStats(){return{entries:this.entries.size,enabled:this.enabled,windowMs:this.windowMs}}};var y=null,k=null,z=!1;function ee(r,e={}){let{captureErrors:t=!0,captureRejections:i=!0}=e,n=d();if(z){n.warn("Error handlers already set up");return}if(!h()){n.log("Not in browser environment, skipping error handlers");return}t&&(y=window.onerror,window.onerror=function(s,o,a,l,u){let c=typeof s=="string"?s:s.type||"Unknown error",b={source:o,lineno:a,colno:l,stack:u==null?void 0:u.stack,errorType:u==null?void 0:u.name};return n.log("Captured error:",c),r("error",c,b),typeof y=="function"?y.call(window,s,o,a,l,u):!1}),i&&(k=window.onunhandledrejection,window.onunhandledrejection=function(s){let o="Unhandled Rejection",a={},l=s.reason;if(l instanceof Error)o=l.message||o,a.stack=l.stack,a.errorType=l.name;else if(typeof l=="string")o=l;else if(l!=null)try{o=JSON.stringify(l)}catch(u){o=String(l)}n.log("Captured unhandled rejection:",o),r("error",o,a),typeof k=="function"&&k.call(window,s)}),z=!0,n.log("Error handlers set up")}function te(){let r=d();h()&&(y!==void 0&&(window.onerror=y),k!==void 0&&(window.onunhandledrejection=k),y=null,k=null,z=!1,r.log("Error handlers torn down"))}var W={enabled:!1,theme:{primary:"#6366f1",background:"#ffffff",text:"#1f2937",accent:"#10b981"},messages:{greeting:"Opa! Algo n\xE3o saiu como esperado.",subtext:"Pode nos ajudar a entender o que aconteceu?",thankYou:"Valeu! J\xE1 estamos olhando isso.",buttonSend:"Enviar",buttonSkip:"Agora n\xE3o"},position:"bottom-right",delay:2e3,maxShowsPerSession:2,cooldownMinutes:30};var O=class{constructor(e,t){this.element=null;this.pupilLeft=null;this.pupilRight=null;this.mouseTrackingEnabled=!0;this.theme=e,this.onClick=t,this.handleMouseMove=this.handleMouseMove.bind(this)}create(){let e=document.createElementNS("http://www.w3.org/2000/svg","svg");return e.setAttribute("viewBox","0 0 100 100"),e.setAttribute("class","blinker-avatar"),e.innerHTML=this.getSVGContent(),e.addEventListener("click",this.onClick),e.addEventListener("mouseenter",()=>this.setState("hover")),e.addEventListener("mouseleave",()=>this.setState("idle")),this.element=e,this.pupilLeft=e.querySelector(".blinker-pupil-left"),this.pupilRight=e.querySelector(".blinker-pupil-right"),document.addEventListener("mousemove",this.handleMouseMove),e}getSVGContent(){return`
|
|
3
|
+
<defs>
|
|
4
|
+
<linearGradient id="blinker-body-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
5
|
+
<stop offset="0%" style="stop-color:${this.theme.primary};stop-opacity:1" />
|
|
6
|
+
<stop offset="100%" style="stop-color:${this.adjustColor(this.theme.primary,-30)};stop-opacity:1" />
|
|
7
|
+
</linearGradient>
|
|
8
|
+
<filter id="blinker-shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
9
|
+
<feDropShadow dx="0" dy="4" stdDeviation="4" flood-opacity="0.2"/>
|
|
10
|
+
</filter>
|
|
11
|
+
</defs>
|
|
12
|
+
|
|
13
|
+
<!-- Glow effect -->
|
|
14
|
+
<ellipse class="blinker-avatar-glow" cx="50" cy="85" rx="25" ry="8" />
|
|
15
|
+
|
|
16
|
+
<!-- Body -->
|
|
17
|
+
<g class="blinker-avatar-body" filter="url(#blinker-shadow)">
|
|
18
|
+
<!-- Main body shape - rounded rectangle with personality -->
|
|
19
|
+
<path d="
|
|
20
|
+
M 25 30
|
|
21
|
+
Q 25 15, 50 15
|
|
22
|
+
Q 75 15, 75 30
|
|
23
|
+
L 75 65
|
|
24
|
+
Q 75 85, 50 85
|
|
25
|
+
Q 25 85, 25 65
|
|
26
|
+
Z
|
|
27
|
+
" fill="url(#blinker-body-gradient)" />
|
|
28
|
+
|
|
29
|
+
<!-- Antenna/Top detail -->
|
|
30
|
+
<circle cx="50" cy="12" r="4" fill="${this.theme.primary}" />
|
|
31
|
+
<line x1="50" y1="16" x2="50" y2="22" stroke="${this.theme.primary}" stroke-width="3" stroke-linecap="round" />
|
|
32
|
+
</g>
|
|
33
|
+
|
|
34
|
+
<!-- Face -->
|
|
35
|
+
<g class="blinker-avatar-face">
|
|
36
|
+
<!-- Left eye container -->
|
|
37
|
+
<ellipse class="blinker-avatar-eye blinker-avatar-eye-left" cx="38" cy="42" rx="10" ry="11" />
|
|
38
|
+
<!-- Right eye container -->
|
|
39
|
+
<ellipse class="blinker-avatar-eye blinker-avatar-eye-right" cx="62" cy="42" rx="10" ry="11" />
|
|
40
|
+
|
|
41
|
+
<!-- Left pupil -->
|
|
42
|
+
<circle class="blinker-avatar-pupil blinker-pupil-left" cx="38" cy="43" r="5" />
|
|
43
|
+
<!-- Right pupil -->
|
|
44
|
+
<circle class="blinker-avatar-pupil blinker-pupil-right" cx="62" cy="43" r="5" />
|
|
45
|
+
|
|
46
|
+
<!-- Eye shine -->
|
|
47
|
+
<circle cx="35" cy="40" r="2" fill="white" opacity="0.8" />
|
|
48
|
+
<circle cx="59" cy="40" r="2" fill="white" opacity="0.8" />
|
|
49
|
+
|
|
50
|
+
<!-- Mouth -->
|
|
51
|
+
<path class="blinker-avatar-mouth" d="M 40 60 Q 50 68, 60 60" />
|
|
52
|
+
</g>
|
|
53
|
+
|
|
54
|
+
<!-- Decorative elements -->
|
|
55
|
+
<circle cx="30" cy="55" r="3" fill="${this.theme.primary}" opacity="0.3" />
|
|
56
|
+
<circle cx="70" cy="55" r="3" fill="${this.theme.primary}" opacity="0.3" />
|
|
57
|
+
`}handleMouseMove(e){if(!this.mouseTrackingEnabled||!this.element||!this.pupilLeft||!this.pupilRight)return;let t=this.element.getBoundingClientRect(),i=t.left+t.width/2,n=t.top+t.height/2,s=(e.clientX-i)/50,o=(e.clientY-n)/50,a=3,l=Math.max(-a,Math.min(a,s)),u=Math.max(-a,Math.min(a,o));this.pupilLeft.setAttribute("transform",`translate(${l}, ${u})`),this.pupilRight.setAttribute("transform",`translate(${l}, ${u})`)}setState(e){this.element&&(this.element.classList.remove("idle","hover","minimized","talking"),this.element.classList.add(e))}setMinimized(e){this.element&&(e?(this.element.classList.add("minimized"),this.mouseTrackingEnabled=!1):(this.element.classList.remove("minimized"),this.mouseTrackingEnabled=!0))}updateTheme(e){this.theme=e,this.element&&(this.element.innerHTML=this.getSVGContent(),this.pupilLeft=this.element.querySelector(".blinker-pupil-left"),this.pupilRight=this.element.querySelector(".blinker-pupil-right"))}adjustColor(e,t){let i=parseInt(e.replace("#",""),16),n=Math.max(0,Math.min(255,(i>>16)+t)),s=Math.max(0,Math.min(255,(i>>8&255)+t)),o=Math.max(0,Math.min(255,(i&255)+t));return`#${(n<<16|s<<8|o).toString(16).padStart(6,"0")}`}getElement(){return this.element}destroy(){document.removeEventListener("mousemove",this.handleMouseMove),this.element&&(this.element.removeEventListener("click",this.onClick),this.element.remove(),this.element=null)}};var D=class{constructor(e,t,i){this.overlay=null;this.dialog=null;this.questions=[];this.answers={};this.errorId="";this.state="questions";this.config=e,this.onSubmit=t,this.onClose=i}open(e,t){this.errorId=e,this.questions=t,this.answers={},this.state="questions",this.render()}close(){this.overlay&&(this.overlay.remove(),this.overlay=null),this.dialog&&(this.dialog.remove(),this.dialog=null),this.onClose()}render(){this.close(),this.overlay=document.createElement("div"),this.overlay.className="blinker-dialog-overlay",this.overlay.addEventListener("click",()=>this.close()),this.dialog=document.createElement("div"),this.dialog.className=`blinker-dialog ${this.config.position}`,this.dialog.innerHTML=this.state==="questions"?this.getQuestionsHTML():this.getThankYouHTML(),document.body.appendChild(this.overlay),document.body.appendChild(this.dialog),this.attachEventListeners()}getQuestionsHTML(){let{messages:e}=this.config;return`
|
|
58
|
+
<div class="blinker-dialog-header">
|
|
59
|
+
<svg class="blinker-dialog-avatar" viewBox="0 0 100 100">
|
|
60
|
+
<defs>
|
|
61
|
+
<linearGradient id="dialog-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
62
|
+
<stop offset="0%" style="stop-color:${this.config.theme.primary}" />
|
|
63
|
+
<stop offset="100%" style="stop-color:${this.adjustColor(this.config.theme.primary,-30)}" />
|
|
64
|
+
</linearGradient>
|
|
65
|
+
</defs>
|
|
66
|
+
<path d="M 25 30 Q 25 15, 50 15 Q 75 15, 75 30 L 75 65 Q 75 85, 50 85 Q 25 85, 25 65 Z" fill="url(#dialog-gradient)" />
|
|
67
|
+
<ellipse cx="38" cy="42" rx="10" ry="11" fill="${this.config.theme.background}" />
|
|
68
|
+
<ellipse cx="62" cy="42" rx="10" ry="11" fill="${this.config.theme.background}" />
|
|
69
|
+
<circle cx="38" cy="43" r="5" fill="${this.config.theme.text}" />
|
|
70
|
+
<circle cx="62" cy="43" r="5" fill="${this.config.theme.text}" />
|
|
71
|
+
<path d="M 40 60 Q 50 68, 60 60" stroke="${this.config.theme.background}" stroke-width="2" fill="none" stroke-linecap="round" />
|
|
72
|
+
</svg>
|
|
73
|
+
<div class="blinker-dialog-title">
|
|
74
|
+
<p class="blinker-dialog-greeting">${e.greeting}</p>
|
|
75
|
+
<p class="blinker-dialog-subtext">${e.subtext}</p>
|
|
76
|
+
</div>
|
|
77
|
+
<button class="blinker-dialog-close" aria-label="Fechar">
|
|
78
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
79
|
+
<path d="M18 6L6 18M6 6l12 12" />
|
|
80
|
+
</svg>
|
|
81
|
+
</button>
|
|
82
|
+
</div>
|
|
83
|
+
<div class="blinker-dialog-body">
|
|
84
|
+
${this.questions.map(t=>this.getQuestionHTML(t)).join("")}
|
|
85
|
+
</div>
|
|
86
|
+
<div class="blinker-dialog-footer">
|
|
87
|
+
<button class="blinker-btn blinker-btn-secondary" data-action="skip">
|
|
88
|
+
${e.buttonSkip}
|
|
89
|
+
</button>
|
|
90
|
+
<button class="blinker-btn blinker-btn-primary" data-action="submit">
|
|
91
|
+
${e.buttonSend}
|
|
92
|
+
</button>
|
|
93
|
+
</div>
|
|
94
|
+
`}getQuestionHTML(e){var i;let t=e.required?" *":"";switch(e.type){case"text":return`
|
|
95
|
+
<div class="blinker-question" data-question-id="${e.id}">
|
|
96
|
+
<label class="blinker-question-label">${e.text}${t}</label>
|
|
97
|
+
<textarea
|
|
98
|
+
class="blinker-question-input blinker-question-textarea"
|
|
99
|
+
placeholder="Digite sua resposta..."
|
|
100
|
+
data-question-id="${e.id}"
|
|
101
|
+
></textarea>
|
|
102
|
+
</div>
|
|
103
|
+
`;case"select":return`
|
|
104
|
+
<div class="blinker-question" data-question-id="${e.id}">
|
|
105
|
+
<label class="blinker-question-label">${e.text}${t}</label>
|
|
106
|
+
<select class="blinker-question-input blinker-question-select" data-question-id="${e.id}">
|
|
107
|
+
<option value="">Selecione...</option>
|
|
108
|
+
${(i=e.options)==null?void 0:i.map(n=>`<option value="${n}">${n}</option>`).join("")}
|
|
109
|
+
</select>
|
|
110
|
+
</div>
|
|
111
|
+
`;case"boolean":return`
|
|
112
|
+
<div class="blinker-question" data-question-id="${e.id}">
|
|
113
|
+
<label class="blinker-question-label">${e.text}${t}</label>
|
|
114
|
+
<div class="blinker-question-boolean">
|
|
115
|
+
<button type="button" data-question-id="${e.id}" data-value="true">Sim</button>
|
|
116
|
+
<button type="button" data-question-id="${e.id}" data-value="false">N\xE3o</button>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
`;default:return""}}getThankYouHTML(){return`
|
|
120
|
+
<div class="blinker-thank-you">
|
|
121
|
+
<svg class="blinker-thank-you-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
122
|
+
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
|
|
123
|
+
<polyline points="22 4 12 14.01 9 11.01" />
|
|
124
|
+
</svg>
|
|
125
|
+
<p class="blinker-thank-you-text">${this.config.messages.thankYou}</p>
|
|
126
|
+
</div>
|
|
127
|
+
`}attachEventListeners(){if(!this.dialog)return;let e=this.dialog.querySelector(".blinker-dialog-close");e==null||e.addEventListener("click",()=>this.close());let t=this.dialog.querySelector('[data-action="submit"]');t==null||t.addEventListener("click",()=>this.handleSubmit());let i=this.dialog.querySelector('[data-action="skip"]');i==null||i.addEventListener("click",()=>this.close()),this.dialog.querySelectorAll("textarea").forEach(a=>{a.addEventListener("input",l=>{let u=l.target,c=u.dataset.questionId;c&&(this.answers[c]=u.value)})}),this.dialog.querySelectorAll("select").forEach(a=>{a.addEventListener("change",l=>{let u=l.target,c=u.dataset.questionId;c&&(this.answers[c]=u.value)})}),this.dialog.querySelectorAll(".blinker-question-boolean button").forEach(a=>{a.addEventListener("click",l=>{let u=l.target,c=u.dataset.questionId,b=u.dataset.value==="true";if(c){this.answers[c]=b;let _=u.parentElement;_==null||_.querySelectorAll("button").forEach(le=>le.classList.remove("selected")),u.classList.add("selected")}})})}handleSubmit(){var n;let e=this.questions.filter(s=>s.required);if(e.some(s=>{let o=this.answers[s.id];return o===void 0||o===""})){let s=e.find(o=>!this.answers[o.id]);if(s){let o=(n=this.dialog)==null?void 0:n.querySelector(`[data-question-id="${s.id}"]`);o instanceof HTMLElement&&(o.focus(),o.style.borderColor="#ef4444",setTimeout(()=>{o.style.borderColor=""},2e3))}return}let i={errorId:this.errorId,answers:{...this.answers},submittedAt:new Date().toISOString()};this.onSubmit(i),this.state="thankyou",this.render(),setTimeout(()=>{this.close()},2500)}updateConfig(e){this.config=e}adjustColor(e,t){let i=parseInt(e.replace("#",""),16),n=Math.max(0,Math.min(255,(i>>16)+t)),s=Math.max(0,Math.min(255,(i>>8&255)+t)),o=Math.max(0,Math.min(255,(i&255)+t));return`#${(n<<16|s<<8|o).toString(16).padStart(6,"0")}`}isOpen(){return this.dialog!==null}};var ve=[{id:"what_doing",text:"O que voc\xEA estava tentando fazer?",type:"text",required:!0}],ye=[{id:"server_error",condition:r=>r.httpCode!==void 0&&r.httpCode>=500,priority:10,questions:[{id:"form_filled",text:"Voc\xEA preencheu algum formul\xE1rio antes disso?",type:"boolean"},{id:"data_lost",text:"Voc\xEA perdeu algum dado importante?",type:"boolean"}]},{id:"network_error",condition:r=>r.message.toLowerCase().includes("network")||r.message.toLowerCase().includes("fetch")||r.message.toLowerCase().includes("failed to fetch")||r.errorType==="TypeError"&&r.message.includes("fetch"),priority:9,questions:[{id:"internet_working",text:"Sua internet est\xE1 funcionando normalmente?",type:"boolean"},{id:"using_vpn",text:"Voc\xEA est\xE1 usando VPN ou proxy?",type:"boolean"}]},{id:"timeout_error",condition:r=>r.message.toLowerCase().includes("timeout")||r.message.toLowerCase().includes("timed out"),priority:8,questions:[{id:"page_slow",text:"A p\xE1gina estava lenta antes do erro?",type:"boolean"},{id:"first_time",text:"\xC9 a primeira vez que isso acontece?",type:"boolean"}]},{id:"auth_error",condition:r=>r.httpCode===401||r.httpCode===403||r.message.toLowerCase().includes("unauthorized")||r.message.toLowerCase().includes("forbidden"),priority:7,questions:[{id:"logged_in",text:"Voc\xEA estava logado no sistema?",type:"boolean"},{id:"session_expired",text:"Ficou muito tempo sem usar o sistema?",type:"boolean"}]},{id:"not_found",condition:r=>r.httpCode===404,priority:6,questions:[{id:"how_arrived",text:"Como voc\xEA chegou nessa p\xE1gina?",type:"select",options:["Digitei o link","Cliquei em um bot\xE3o","Usei o menu","Outro"]}]},{id:"validation_error",condition:r=>r.httpCode===400||r.httpCode===422||r.message.toLowerCase().includes("validation")||r.message.toLowerCase().includes("invalid"),priority:5,questions:[{id:"what_filled",text:"O que voc\xEA preencheu no formul\xE1rio?",type:"text"},{id:"special_chars",text:"Usou caracteres especiais ou emojis?",type:"boolean"}]},{id:"ui_error",condition:r=>r.errorType==="TypeError"||r.message.toLowerCase().includes("undefined")||r.message.toLowerCase().includes("null"),priority:4,questions:[{id:"clicked_what",text:"Voc\xEA clicou em algo espec\xEDfico?",type:"text"},{id:"page_loaded",text:"A p\xE1gina tinha carregado completamente?",type:"boolean"}]},{id:"load_error",condition:r=>r.message.toLowerCase().includes("chunk")||r.message.toLowerCase().includes("loading")||r.message.toLowerCase().includes("script"),priority:3,questions:[{id:"refreshed",text:"Voc\xEA tentou atualizar a p\xE1gina?",type:"boolean"},{id:"browser",text:"Qual navegador voc\xEA est\xE1 usando?",type:"select",options:["Chrome","Firefox","Safari","Edge","Outro"]}]}],ke=[{id:"happened_before",text:"Isso j\xE1 aconteceu antes?",type:"boolean"},{id:"additional_info",text:"Algo mais que possa nos ajudar?",type:"text",required:!1}],F=class{inferQuestions(e,t){let i={message:e,type:"error",httpCode:t==null?void 0:t.httpCode,errorType:t==null?void 0:t.errorType,stack:t==null?void 0:t.stack},n=ye.filter(a=>a.condition(i)).sort((a,l)=>l.priority-a.priority),s=[...ve],o=new Set(s.map(a=>a.id));for(let a of n.slice(0,2))for(let l of a.questions)o.has(l.id)||(s.push(l),o.add(l.id));if(s.length<3)for(let a of ke)!o.has(a.id)&&s.length<4&&(s.push(a),o.add(a.id));return s.slice(0,4)}shouldShowWidget(e,t,i){if(i!==void 0)return i;if((t==null?void 0:t.httpCode)!==void 0&&(t.httpCode>=500||t.httpCode===400||t.httpCode===422))return!0;let n=["unexpected","critical","fatal","crash","failed to","cannot read","cannot access","undefined is not","null is not"],s=e.toLowerCase();return n.some(o=>s.includes(o))}};function ie(r){if(document.getElementById("blinker-widget-styles"))return;let e=document.createElement("style");e.id="blinker-widget-styles",e.textContent=oe(r),document.head.appendChild(e)}function re(){let r=document.getElementById("blinker-widget-styles");r&&r.remove()}function ne(r){let e=document.getElementById("blinker-widget-styles");e&&(e.textContent=oe(r))}function oe(r){return`
|
|
128
|
+
@keyframes blinker-breathe {
|
|
129
|
+
0%, 100% { transform: scale(1); }
|
|
130
|
+
50% { transform: scale(1.05); }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@keyframes blinker-pulse {
|
|
134
|
+
0%, 100% { opacity: 1; }
|
|
135
|
+
50% { opacity: 0.7; }
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@keyframes blinker-float {
|
|
139
|
+
0%, 100% { transform: translateY(0); }
|
|
140
|
+
50% { transform: translateY(-5px); }
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@keyframes blinker-fade-in {
|
|
144
|
+
from { opacity: 0; transform: scale(0.8) translateY(20px); }
|
|
145
|
+
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@keyframes blinker-fade-out {
|
|
149
|
+
from { opacity: 1; transform: scale(1) translateY(0); }
|
|
150
|
+
to { opacity: 0; transform: scale(0.8) translateY(20px); }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@keyframes blinker-slide-up {
|
|
154
|
+
from { opacity: 0; transform: translateY(30px); }
|
|
155
|
+
to { opacity: 1; transform: translateY(0); }
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@keyframes blinker-eye-blink {
|
|
159
|
+
0%, 45%, 55%, 100% { transform: scaleY(1); }
|
|
160
|
+
50% { transform: scaleY(0.1); }
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
@keyframes blinker-glow {
|
|
164
|
+
0%, 100% { filter: drop-shadow(0 0 8px ${r.primary}40); }
|
|
165
|
+
50% { filter: drop-shadow(0 0 15px ${r.primary}60); }
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.blinker-widget-container {
|
|
169
|
+
position: fixed;
|
|
170
|
+
z-index: 999999;
|
|
171
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.blinker-widget-container.bottom-right {
|
|
175
|
+
bottom: 20px;
|
|
176
|
+
right: 20px;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.blinker-widget-container.bottom-left {
|
|
180
|
+
bottom: 20px;
|
|
181
|
+
left: 20px;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.blinker-avatar {
|
|
185
|
+
width: 60px;
|
|
186
|
+
height: 60px;
|
|
187
|
+
cursor: pointer;
|
|
188
|
+
animation: blinker-float 3s ease-in-out infinite, blinker-glow 2s ease-in-out infinite;
|
|
189
|
+
transition: transform 0.3s ease;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.blinker-avatar:hover {
|
|
193
|
+
transform: scale(1.1);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.blinker-avatar.minimized {
|
|
197
|
+
width: 40px;
|
|
198
|
+
height: 40px;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.blinker-avatar-body {
|
|
202
|
+
fill: ${r.primary};
|
|
203
|
+
animation: blinker-breathe 4s ease-in-out infinite;
|
|
204
|
+
transform-origin: center;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.blinker-avatar-eye {
|
|
208
|
+
fill: ${r.background};
|
|
209
|
+
animation: blinker-eye-blink 4s ease-in-out infinite;
|
|
210
|
+
transform-origin: center;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.blinker-avatar-eye-left {
|
|
214
|
+
animation-delay: 0.1s;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.blinker-avatar-pupil {
|
|
218
|
+
fill: ${r.text};
|
|
219
|
+
transition: transform 0.1s ease;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.blinker-avatar-mouth {
|
|
223
|
+
stroke: ${r.background};
|
|
224
|
+
stroke-width: 2;
|
|
225
|
+
fill: none;
|
|
226
|
+
stroke-linecap: round;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.blinker-avatar-glow {
|
|
230
|
+
fill: ${r.primary};
|
|
231
|
+
opacity: 0.3;
|
|
232
|
+
animation: blinker-pulse 2s ease-in-out infinite;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.blinker-dialog-overlay {
|
|
236
|
+
position: fixed;
|
|
237
|
+
top: 0;
|
|
238
|
+
left: 0;
|
|
239
|
+
right: 0;
|
|
240
|
+
bottom: 0;
|
|
241
|
+
background: rgba(0, 0, 0, 0.3);
|
|
242
|
+
z-index: 999998;
|
|
243
|
+
animation: blinker-fade-in 0.3s ease;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
.blinker-dialog {
|
|
247
|
+
position: fixed;
|
|
248
|
+
z-index: 999999;
|
|
249
|
+
width: 340px;
|
|
250
|
+
max-width: calc(100vw - 40px);
|
|
251
|
+
background: ${r.background};
|
|
252
|
+
border-radius: 16px;
|
|
253
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
254
|
+
animation: blinker-slide-up 0.4s ease;
|
|
255
|
+
overflow: hidden;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.blinker-dialog.bottom-right {
|
|
259
|
+
bottom: 90px;
|
|
260
|
+
right: 20px;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.blinker-dialog.bottom-left {
|
|
264
|
+
bottom: 90px;
|
|
265
|
+
left: 20px;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.blinker-dialog-header {
|
|
269
|
+
padding: 20px 20px 0;
|
|
270
|
+
display: flex;
|
|
271
|
+
align-items: flex-start;
|
|
272
|
+
gap: 12px;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.blinker-dialog-avatar {
|
|
276
|
+
width: 40px;
|
|
277
|
+
height: 40px;
|
|
278
|
+
flex-shrink: 0;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.blinker-dialog-title {
|
|
282
|
+
flex: 1;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.blinker-dialog-greeting {
|
|
286
|
+
font-size: 16px;
|
|
287
|
+
font-weight: 600;
|
|
288
|
+
color: ${r.text};
|
|
289
|
+
margin: 0 0 4px;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.blinker-dialog-subtext {
|
|
293
|
+
font-size: 13px;
|
|
294
|
+
color: ${r.text}99;
|
|
295
|
+
margin: 0;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.blinker-dialog-close {
|
|
299
|
+
background: none;
|
|
300
|
+
border: none;
|
|
301
|
+
padding: 4px;
|
|
302
|
+
cursor: pointer;
|
|
303
|
+
color: ${r.text}66;
|
|
304
|
+
border-radius: 6px;
|
|
305
|
+
transition: all 0.2s;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.blinker-dialog-close:hover {
|
|
309
|
+
background: ${r.text}10;
|
|
310
|
+
color: ${r.text};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.blinker-dialog-body {
|
|
314
|
+
padding: 20px;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.blinker-question {
|
|
318
|
+
margin-bottom: 16px;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.blinker-question:last-child {
|
|
322
|
+
margin-bottom: 0;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.blinker-question-label {
|
|
326
|
+
display: block;
|
|
327
|
+
font-size: 14px;
|
|
328
|
+
font-weight: 500;
|
|
329
|
+
color: ${r.text};
|
|
330
|
+
margin-bottom: 8px;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.blinker-question-input {
|
|
334
|
+
width: 100%;
|
|
335
|
+
padding: 10px 12px;
|
|
336
|
+
border: 1px solid ${r.text}20;
|
|
337
|
+
border-radius: 8px;
|
|
338
|
+
font-size: 14px;
|
|
339
|
+
color: ${r.text};
|
|
340
|
+
background: ${r.background};
|
|
341
|
+
transition: border-color 0.2s, box-shadow 0.2s;
|
|
342
|
+
box-sizing: border-box;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.blinker-question-input:focus {
|
|
346
|
+
outline: none;
|
|
347
|
+
border-color: ${r.primary};
|
|
348
|
+
box-shadow: 0 0 0 3px ${r.primary}20;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.blinker-question-input::placeholder {
|
|
352
|
+
color: ${r.text}50;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.blinker-question-textarea {
|
|
356
|
+
resize: vertical;
|
|
357
|
+
min-height: 80px;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.blinker-question-select {
|
|
361
|
+
appearance: none;
|
|
362
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
|
|
363
|
+
background-repeat: no-repeat;
|
|
364
|
+
background-position: right 12px center;
|
|
365
|
+
padding-right: 36px;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.blinker-question-boolean {
|
|
369
|
+
display: flex;
|
|
370
|
+
gap: 8px;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.blinker-question-boolean button {
|
|
374
|
+
flex: 1;
|
|
375
|
+
padding: 10px;
|
|
376
|
+
border: 1px solid ${r.text}20;
|
|
377
|
+
border-radius: 8px;
|
|
378
|
+
background: ${r.background};
|
|
379
|
+
color: ${r.text};
|
|
380
|
+
font-size: 14px;
|
|
381
|
+
cursor: pointer;
|
|
382
|
+
transition: all 0.2s;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.blinker-question-boolean button:hover {
|
|
386
|
+
border-color: ${r.primary};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.blinker-question-boolean button.selected {
|
|
390
|
+
background: ${r.primary};
|
|
391
|
+
border-color: ${r.primary};
|
|
392
|
+
color: white;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.blinker-dialog-footer {
|
|
396
|
+
padding: 16px 20px 20px;
|
|
397
|
+
display: flex;
|
|
398
|
+
gap: 8px;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.blinker-btn {
|
|
402
|
+
flex: 1;
|
|
403
|
+
padding: 12px 16px;
|
|
404
|
+
border-radius: 8px;
|
|
405
|
+
font-size: 14px;
|
|
406
|
+
font-weight: 500;
|
|
407
|
+
cursor: pointer;
|
|
408
|
+
transition: all 0.2s;
|
|
409
|
+
border: none;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.blinker-btn-primary {
|
|
413
|
+
background: ${r.accent};
|
|
414
|
+
color: white;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.blinker-btn-primary:hover {
|
|
418
|
+
filter: brightness(1.1);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.blinker-btn-primary:disabled {
|
|
422
|
+
opacity: 0.5;
|
|
423
|
+
cursor: not-allowed;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.blinker-btn-secondary {
|
|
427
|
+
background: ${r.text}10;
|
|
428
|
+
color: ${r.text}99;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.blinker-btn-secondary:hover {
|
|
432
|
+
background: ${r.text}20;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.blinker-thank-you {
|
|
436
|
+
text-align: center;
|
|
437
|
+
padding: 40px 20px;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
.blinker-thank-you-icon {
|
|
441
|
+
width: 48px;
|
|
442
|
+
height: 48px;
|
|
443
|
+
margin: 0 auto 16px;
|
|
444
|
+
color: ${r.accent};
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
.blinker-thank-you-text {
|
|
448
|
+
font-size: 16px;
|
|
449
|
+
color: ${r.text};
|
|
450
|
+
margin: 0;
|
|
451
|
+
}
|
|
452
|
+
`}var se="blinker_widget_state",S=class{constructor(e){this.container=null;this.avatar=null;this.dialog=null;this.onFeedbackSubmit=null;this.config={...W,...e},this.state=this.loadState(),this.questionEngine=new F}init(e){this.config.enabled&&typeof document!="undefined"&&(this.onFeedbackSubmit=e||null,ie(this.config.theme),this.createContainer())}createContainer(){if(this.container)return;this.container=document.createElement("div"),this.container.className=`blinker-widget-container ${this.config.position}`,document.body.appendChild(this.container),this.avatar=new O(this.config.theme,()=>this.handleAvatarClick());let e=this.avatar.create();this.container.appendChild(e),this.dialog=new D(this.config,t=>this.handleFeedbackSubmit(t),()=>this.handleDialogClose()),this.hide()}show(e,t,i,n){if(!this.config.enabled||!this.container||!this.avatar||!this.questionEngine.shouldShowWidget(t,i,n)||!this.canShowWidget())return;let o=this.questionEngine.inferQuestions(t,i);this.state.currentErrorId=e,this.state.questions=o,this.state.isVisible=!0,this.state.showCount++,this.state.lastShowTime=Date.now(),this.saveState(),this.container.style.display="block",this.avatar.setMinimized(!1)}hide(){this.container&&(this.state.isVisible=!1,this.state.isDialogOpen=!1,this.container.style.display="none")}handleAvatarClick(){var e;!this.dialog||!this.state.currentErrorId||(this.state.isDialogOpen?this.dialog.close():(this.state.isDialogOpen=!0,this.dialog.open(this.state.currentErrorId,this.state.questions),(e=this.avatar)==null||e.setMinimized(!0)))}handleFeedbackSubmit(e){this.onFeedbackSubmit&&this.onFeedbackSubmit(e)}handleDialogClose(){var e;this.state.isDialogOpen=!1,(e=this.avatar)==null||e.setMinimized(!1),setTimeout(()=>{this.hide()},500)}canShowWidget(){if(this.state.showCount>=this.config.maxShowsPerSession)return!1;if(this.state.lastShowTime){let e=this.config.cooldownMinutes*60*1e3;if(Date.now()-this.state.lastShowTime<e)return!1}return!0}loadState(){let e={isVisible:!1,isMinimized:!1,isDialogOpen:!1,currentErrorId:null,questions:[],showCount:0,lastShowTime:null};if(typeof sessionStorage=="undefined")return e;try{let t=sessionStorage.getItem(se);if(t){let i=JSON.parse(t);return{...e,showCount:i.showCount||0,lastShowTime:i.lastShowTime||null}}}catch(t){}return e}saveState(){if(typeof sessionStorage!="undefined")try{sessionStorage.setItem(se,JSON.stringify({showCount:this.state.showCount,lastShowTime:this.state.lastShowTime}))}catch(e){}}updateConfig(e){var t,i;this.config={...this.config,...e},e.theme&&(ne(this.config.theme),(t=this.avatar)==null||t.updateTheme(this.config.theme)),(i=this.dialog)==null||i.updateConfig(this.config)}getConfig(){return{...this.config}}isVisible(){return this.state.isVisible}isDialogOpen(){return this.state.isDialogOpen}destroy(){var e,t;(e=this.avatar)==null||e.destroy(),(t=this.dialog)==null||t.close(),this.container&&(this.container.remove(),this.container=null),re(),this.avatar=null,this.dialog=null}};var m=class{constructor(){this.config=null;this.initialized=!1;this.filterEngine=null;this.queue=null;this.sessionManager=null;this.userContext=null;this.rateLimiter=null;this.sampler=null;this.deduplicator=null;this.widget=null}get version(){return w}init(e){var n,s,o,a;if(this.initialized){d().warn("SDK already initialized");return}if(!e.token)throw new Error("[Blinker] Token is required");if(!((n=e.enabled)!=null?n:g.enabled)){C((s=e.debug)!=null?s:!1),d().log("SDK disabled via config"),this.config={...g,...e};return}this.config={...g,...e},C((o=this.config.debug)!=null?o:!1);let i=d();this.filterEngine=new T(e.filters),i.log("Filter engine initialized"),this.queue=new L(e.token,{endpoint:this.config.endpoint,enableBatching:this.config.enableBatching,batchSize:this.config.batchSize,flushInterval:this.config.flushInterval,enableOfflineStorage:this.config.enableOfflineStorage,maxStoredEvents:this.config.maxStoredEvents,onError:this.config.onError}),i.log("Event queue initialized"),this.sessionManager=new M,this.userContext=new q(this.sessionManager),i.log("Context managers initialized"),this.rateLimiter=new A(this.config.maxEventsPerMinute),this.sampler=new R(this.config.sampleRate),i.log("Sampling modules initialized"),this.deduplicator=new $(this.config.enableDeduplication,this.config.deduplicationWindow),i.log("Deduplicator initialized"),(this.config.captureErrors||this.config.captureRejections)&&(ee((l,u,c)=>this.handleCapturedError(l,u,c),{captureErrors:this.config.captureErrors,captureRejections:this.config.captureRejections}),i.log("Error handlers set up")),(a=this.config.widget)!=null&&a.enabled&&(this.widget=new S(this.config.widget),this.widget.init(l=>this.handleWidgetFeedback(l)),i.log("Widget initialized")),this.initialized=!0,i.log("SDK initialized successfully")}handleCapturedError(e,t,i){var o,a,l,u,c;if(!((o=this.filterEngine)!=null&&o.shouldCapture(t,i.errorType,i.httpCode)))return;let n=(a=this.deduplicator)==null?void 0:a.check(t,i.stack);if(n&&!n.shouldSend)return;let s=v();this.track(e,t,{...i,errorId:s,count:n==null?void 0:n.count}),this.widget&&((u=(l=this.config)==null?void 0:l.widget)!=null&&u.enabled)&&setTimeout(()=>{var b;(b=this.widget)==null||b.show(s,t,i)},(c=this.config.widget.delay)!=null?c:2e3)}handleWidgetFeedback(e){d().log("Widget feedback received:",e.errorId),this.track("feedback","User feedback submitted",{errorId:e.errorId,answers:e.answers,submittedAt:e.submittedAt})}track(e,t,i){var l,u,c;if(!this.config)return Promise.resolve({success:!1,error:"SDK not initialized"});if(!this.config.enabled)return Promise.resolve({success:!0,error:"SDK disabled"});if(!this.initialized)return Promise.resolve({success:!1,error:"SDK not initialized"});let n=d(),s=e==="error";if(!((l=this.rateLimiter)!=null&&l.allow()))return n.log("Event dropped due to rate limit"),Promise.resolve({success:!1,error:"Rate limited"});if(!((u=this.sampler)!=null&&u.shouldSample(s)))return Promise.resolve({success:!0,error:"Sampled out"});let o=(c=this.userContext)==null?void 0:c.getEventContext(),a={id:v(),type:e,message:t,payload:i,timestamp:new Date().toISOString(),url:V(),userAgent:j(),sessionId:o==null?void 0:o.sessionId,userId:o==null?void 0:o.userId,userTraits:o==null?void 0:o.userTraits,context:o==null?void 0:o.custom};return this.config.onBeforeSend&&(a=this.config.onBeforeSend(a),!a)?(n.log("Event filtered by onBeforeSend"),Promise.resolve({success:!0,error:"Filtered by onBeforeSend"})):(n.log("Tracking event:",e,t.substring(0,50)),this.queue.add(a))}captureError(e,t){var u,c;let i=e instanceof Error?e.message:e,n=e instanceof Error?e.name:void 0,s=e instanceof Error?e.stack:void 0,o=t==null?void 0:t.httpCode;if(!((u=this.filterEngine)!=null&&u.shouldCapture(i,n,o)))return Promise.resolve({success:!0,error:"Filtered out"});let a=(c=this.deduplicator)==null?void 0:c.check(i,s);if(a&&!a.shouldSend)return Promise.resolve({success:!0,error:"Deduplicated"});let l={...t,errorType:n,stack:s,count:a==null?void 0:a.count};return this.track("error",i,l)}trackPageView(e,t){var n;let i=e||G();return(n=this.sessionManager)==null||n.recordPageView(),this.track("pageview",i,{...t,referrer:K()})}identify(e,t){var i;(i=this.userContext)==null||i.identify(e,t)}setContext(e,t){var i;(i=this.userContext)==null||i.setContext(e,t)}getContext(){var e,t;return(t=(e=this.userContext)==null?void 0:e.getCustomContext())!=null?t:{}}clearContext(){var e;(e=this.userContext)==null||e.clearAll()}getSessionId(){var e,t;return(t=(e=this.sessionManager)==null?void 0:e.getSessionId())!=null?t:""}getSession(){var e,t;return(t=(e=this.sessionManager)==null?void 0:e.getSession())!=null?t:null}async flush(){var e;await((e=this.queue)==null?void 0:e.flush())}getQueueSize(){var e,t;return(t=(e=this.queue)==null?void 0:e.size())!=null?t:0}isInitialized(){return this.initialized}getConfig(){if(!this.config)return null;let{token:e,...t}=this.config;return t}getFilters(){var e,t;return(t=(e=this.filterEngine)==null?void 0:e.getFilters())!=null?t:{...p}}showWidget(e,t,i){var n;(n=this.widget)==null||n.show(e,t,i)}hideWidget(){var e;(e=this.widget)==null||e.hide()}getWidgetConfig(){var e,t;return(t=(e=this.widget)==null?void 0:e.getConfig())!=null?t:null}updateWidgetConfig(e){var t;(t=this.widget)==null||t.updateConfig(e)}isWidgetVisible(){var e,t;return(t=(e=this.widget)==null?void 0:e.isVisible())!=null?t:!1}destroy(){var t,i,n,s;let e=d();(t=this.queue)==null||t.destroy(),te(),(i=this.deduplicator)==null||i.destroy(),(n=this.sessionManager)==null||n.endSession(),(s=this.widget)==null||s.destroy(),this.config=null,this.initialized=!1,this.filterEngine=null,this.queue=null,this.sessionManager=null,this.userContext=null,this.rateLimiter=null,this.sampler=null,this.deduplicator=null,this.widget=null,e.log("SDK destroyed"),C(!1)}};var ae=new m;var xe=ae;return pe(Se);})();
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { DeduplicationEntry } from './types';
|
|
2
|
+
export interface DeduplicationResult {
|
|
3
|
+
shouldSend: boolean;
|
|
4
|
+
fingerprint: string;
|
|
5
|
+
count: number;
|
|
6
|
+
isDuplicate: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare class Deduplicator {
|
|
9
|
+
private enabled;
|
|
10
|
+
private windowMs;
|
|
11
|
+
private entries;
|
|
12
|
+
private cleanupTimer;
|
|
13
|
+
constructor(enabled?: boolean, windowMs?: number);
|
|
14
|
+
check(message: string, stack?: string): DeduplicationResult;
|
|
15
|
+
getCount(fingerprint: string): number;
|
|
16
|
+
flush(): DeduplicationEntry[];
|
|
17
|
+
private startCleanup;
|
|
18
|
+
private cleanup;
|
|
19
|
+
destroy(): void;
|
|
20
|
+
getStats(): {
|
|
21
|
+
entries: number;
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
windowMs: number;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=deduplication.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deduplication.d.ts","sourceRoot":"","sources":["../../src/capture/deduplication.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAKlD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAA8C;IAC7D,OAAO,CAAC,YAAY,CAA+C;gBAEvD,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM;IAShD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,mBAAmB;IAiD3D,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAIrC,KAAK,IAAI,kBAAkB,EAAE;IAM7B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,OAAO;IAiBf,OAAO,IAAI,IAAI;IAQf,QAAQ,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;CAOpE"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ErrorCallback, ErrorHandlerOptions } from './types';
|
|
2
|
+
export declare function setupErrorHandlers(callback: ErrorCallback, options?: ErrorHandlerOptions): void;
|
|
3
|
+
export declare function teardownErrorHandlers(): void;
|
|
4
|
+
export declare function isErrorHandlersSetup(): boolean;
|
|
5
|
+
//# sourceMappingURL=errorHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/capture/errorHandler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAQlE,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,aAAa,EACvB,OAAO,GAAE,mBAAwB,GAChC,IAAI,CA+EN;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAoB5C;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/capture/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BlinkerErrorPayload } from '../core/types';
|
|
2
|
+
export type ErrorCallback = (type: string, message: string, payload: BlinkerErrorPayload) => void;
|
|
3
|
+
export interface ErrorHandlerOptions {
|
|
4
|
+
captureErrors?: boolean;
|
|
5
|
+
captureRejections?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface DeduplicationEntry {
|
|
8
|
+
fingerprint: string;
|
|
9
|
+
firstSeen: number;
|
|
10
|
+
count: number;
|
|
11
|
+
lastSeen: number;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/capture/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,MAAM,aAAa,GAAG,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,mBAAmB,KACzB,IAAI,CAAC;AAEV,MAAM,WAAW,mBAAmB;IAClC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SessionInfo } from './types';
|
|
2
|
+
export declare class SessionManager {
|
|
3
|
+
private session;
|
|
4
|
+
private readonly storageKey;
|
|
5
|
+
private storageAvailable;
|
|
6
|
+
constructor();
|
|
7
|
+
private initSession;
|
|
8
|
+
getSessionId(): string;
|
|
9
|
+
getSession(): SessionInfo;
|
|
10
|
+
recordPageView(): void;
|
|
11
|
+
touch(): void;
|
|
12
|
+
getDuration(): number;
|
|
13
|
+
private persist;
|
|
14
|
+
endSession(): void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=SessionManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../src/context/SessionManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAM3C,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwB;IACnD,OAAO,CAAC,gBAAgB,CAAU;;IAOlC,OAAO,CAAC,WAAW;IA2BnB,YAAY,IAAI,MAAM;IAItB,UAAU,IAAI,WAAW;IAOzB,cAAc,IAAI,IAAI;IAQtB,KAAK,IAAI,IAAI;IAOb,WAAW,IAAI,MAAM;IAMrB,OAAO,CAAC,OAAO;IAUf,UAAU,IAAI,IAAI;CAUnB"}
|