@sprig-technologies/sprig-browser
Version:
npm package for the sprig web sdk
2 lines (1 loc) • 30.7 kB
JavaScript
;var qe=Object.defineProperty;var ze=(e,t,r)=>t in e?qe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var $=(e,t,r)=>(ze(e,typeof t!="symbol"?t+"":t,r),r);const s=require("./metricsReporter-Cdy0iTSw.cjs");var k=(e=>(e[e.DomContentLoaded=0]="DomContentLoaded",e[e.Load=1]="Load",e[e.FullSnapshot=2]="FullSnapshot",e[e.IncrementalSnapshot=3]="IncrementalSnapshot",e[e.Meta=4]="Meta",e[e.Custom=5]="Custom",e[e.Plugin=6]="Plugin",e))(k||{}),D=(e=>(e[e.Mutation=0]="Mutation",e[e.MouseMove=1]="MouseMove",e[e.MouseInteraction=2]="MouseInteraction",e[e.Scroll=3]="Scroll",e[e.ViewportResize=4]="ViewportResize",e[e.Input=5]="Input",e[e.TouchMove=6]="TouchMove",e[e.MediaInteraction=7]="MediaInteraction",e[e.StyleSheetRule=8]="StyleSheetRule",e[e.CanvasMutation=9]="CanvasMutation",e[e.Font=10]="Font",e[e.Log=11]="Log",e[e.Drag=12]="Drag",e[e.StyleDeclaration=13]="StyleDeclaration",e[e.Selection=14]="Selection",e[e.AdoptedStyleSheet=15]="AdoptedStyleSheet",e[e.CustomElement=16]="CustomElement",e))(D||{});const z=(e,t)=>t.some(r=>e instanceof r);let ue,le;const Q=new WeakMap,K=new WeakMap,F=new WeakMap;let X={get(e,t,r){if(e instanceof IDBTransaction){if(t==="done")return Q.get(e);if(t==="store")return r.objectStoreNames[1]?void 0:r.objectStore(r.objectStoreNames[0])}return R(e[t])},set:(e,t,r)=>(e[t]=r,!0),has:(e,t)=>e instanceof IDBTransaction&&(t==="done"||t==="store")||t in e};function he(e){X=e(X)}function Qe(e){return(le||(le=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])).includes(e)?function(...t){return e.apply(Y(this),t),R(this.request)}:function(...t){return R(e.apply(Y(this),t))}}function Xe(e){return typeof e=="function"?Qe(e):(e instanceof IDBTransaction&&function(t){if(Q.has(t))return;const r=new Promise((n,a)=>{const o=()=>{a(t.error||new DOMException("AbortError","AbortError"))};t.oncomplete=()=>{n()},t.onerror=o,t.onabort=o});Q.set(t,r)}(e),z(e,ue||(ue=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction]))?new Proxy(e,X):e)}function R(e){if(e instanceof IDBRequest)return function(r){const n=new Promise((a,o)=>{r.onsuccess=()=>{a(R(r.result))},r.onerror=()=>{o(r.error)}});return F.set(n,r),n}(e);if(K.has(e))return K.get(e);const t=Xe(e);return t!==e&&(K.set(e,t),F.set(t,e)),t}const Y=e=>F.get(e);function Z(e,{blocked:t}={}){const r=indexedDB.deleteDatabase(e);return t&&(r.onblocked=n=>t(n.oldVersion,n)),R(r).then(()=>{})}const Ye=["get","getKey","getAll","getAllKeys","count"],Ze=["put","add","delete","clear"],W=new Map;function pe(e,t){if(!(e instanceof IDBDatabase)||t in e||typeof t!="string")return;if(W.get(t))return W.get(t);const r=t.replace(/FromIndex$/,""),n=t!==r,a=Ze.includes(r);if(!(r in(n?IDBIndex:IDBObjectStore).prototype)||!a&&!Ye.includes(r))return;const o=async function(i,...c){const d=this.transaction(i,a?"readwrite":"readonly");let u=d.store;return n&&(u=u.index(c.shift())),(await Promise.all([u[r](...c),a&&d.done]))[0]};return W.set(t,o),o}he(e=>({...e,get:(t,r,n)=>pe(t,r)||e.get(t,r,n),has:(t,r)=>!!pe(t,r)||e.has(t,r)}));const et=["continue","continuePrimaryKey","advance"],ge={},ee=new WeakMap,Ie=new WeakMap,tt={get(e,t){if(!et.includes(t))return e[t];let r=ge[t];return r||(r=ge[t]=function(...n){ee.set(this,Ie.get(this)[t](...n))}),r}};async function*rt(...e){let t=this;if(t instanceof IDBCursor||(t=await t.openCursor(...e)),!t)return;const r=new Proxy(t,tt);for(Ie.set(r,t),F.set(r,Y(t));t;)yield r,t=await(ee.get(r)||t.continue()),ee.delete(r)}function me(e,t){return t===Symbol.asyncIterator&&z(e,[IDBIndex,IDBObjectStore,IDBCursor])||t==="iterate"&&z(e,[IDBIndex,IDBObjectStore])}he(e=>({...e,get:(t,r,n)=>me(t,r)?rt:e.get(t,r,n),has:(t,r)=>me(t,r)||e.has(t,r)}));const be=new class{constructor(e){$(this,"awaitingResolvers",[]);$(this,"activeCount",0);this.capacity=e}async acquire(){if(!(this.activeCount<this.capacity))return new Promise(e=>{this.awaitingResolvers.push(e)});this.activeCount++}release(){const e=this.awaitingResolvers.shift();e&&this.activeCount<=this.capacity?e():this.activeCount--}async execute(e){try{return await this.acquire(),await e()}finally{this.release()}}setLimit(e){this.capacity=e}}(2),ve=async({apiUrl:e,surveyId:t,uploadId:r,etags:n,headers:a,responseGroupUuid:o,replayDuration:i,eventDigest:c},d=!1)=>{var y;if(!d&&!r&&!n)return void s.breadcrumbsLogger.error("UploadErr",{isMobile:d,uploadId:r,etags:n});s.breadcrumbsLogger.info("MarkUploadComplete",{surveyId:t});const u=await s.sprigFetch(`${e}/sdk/1/completeSessionReplay`,{method:"POST",body:JSON.stringify({etags:n,uploadId:r,responseGroupUuid:o,surveyId:t,replayDuration:i,eventDigest:c,userAgent:(y=window==null?void 0:window.navigator)==null?void 0:y.userAgent}),headers:a,shouldRetryRequest:!0});return s.breadcrumbsLogger.info("MarkUploadDone",{surveyId:t}),u},nt=e=>{if(e instanceof Attr)return null;let t=1;for(let r=e.previousSibling;r;r=r.previousSibling)r.nodeName===e.nodeName&&++t;return t},Se=e=>{if(e===null)return"";const t=[];if(e instanceof Document)return"/";for(let r=e;r&&!(r instanceof Document)&&r!==null;r=r instanceof Attr?r.ownerElement:r.parentElement){const n=t[t.length]={name:void 0,position:null};switch(r.nodeType){case Node.TEXT_NODE:n.name="text()";break;case Node.ATTRIBUTE_NODE:n.name="@"+r.nodeName;break;case Node.PROCESSING_INSTRUCTION_NODE:n.name="processing-instruction()";break;case Node.COMMENT_NODE:n.name="comment()";break;case Node.ELEMENT_NODE:n.name=r.nodeName}n.position=nt(r)}return"/"+t.reverse().map(r=>r.position!==null?`/${r.name}[${r.position}]`:`/${r.name}`).join("")},b={capture:!0,passive:!0},at=["a","button","input","option","li","link"],ot=["Escape","Enter","Backspace","F5","Tab"];let j=!1;const st=["label","type","role","title","placeholder","errormessage","valuetext","href"],it="aria-",we=e=>{var n;if(((n=e.tagName)==null?void 0:n.toLowerCase())==="html")return{element:"html"};const t=e.textContent,r=t?{text:t}:{};r.element=(a=>{if(!a.tagName)return"No tagName";const o=a.getAttribute("type");return o?`${o} ${a.tagName.toLowerCase()}`:a.tagName.toLowerCase()})(e);for(const a of e.attributes){let o=a.name;const i=a.value;o.startsWith(it)&&(o=o.substring(5)),st.includes(o)&&(r[o]=i)}return r},dt=e=>{var n;if(!e)return{};const t={...we(e)},r=e.parentElement;if(r&&at.includes((n=r.tagName)==null?void 0:n.toLowerCase())){const a=we(r);Object.assign(t,a)}return t},De=(e,t)=>{var n;let r=t.target;t.target===((n=window.document)==null?void 0:n.body)&&window.Sprig.pointerDownTarget&&(r=window.Sprig.pointerDownTarget),ut({x:t.x,y:t.y,type:e,elementAttributes:dt(r),windowHeight:window.innerHeight,windowWidth:window.innerWidth,...r instanceof HTMLElement?{rect:r==null?void 0:r.getBoundingClientRect(),xPath:Se(r)}:{}})},Ee=e=>{ot.includes(e.key)&>({key:e.key})},Ce=((e,t)=>{let r;return n=>{clearTimeout(r),r=window.setTimeout(()=>e(n),t)}})(e=>{if(!(e.target instanceof HTMLElement||e.target instanceof Document))return;let t=e.target;"scrollTop"in t||(t=t.documentElement),mt({xPath:Se(t),x:t.scrollLeft,y:t.scrollTop,elementAttributes:{targetScrollWidth:t.scrollWidth,targetClientWidth:t.clientWidth,targetScrollHeight:t.scrollHeight,targetClientHeight:t.clientHeight}})},750),ke=(ye="left_click",e=>De(ye,e));var ye;const Re=e=>{e.button===2&&De("right_click",e)},Ue=e=>{window.Sprig&&(window.Sprig.pointerDownTarget=e.target)},ct=()=>{j||(window.addEventListener("click",ke,b),window.addEventListener("pointerdown",Ue,b),window.addEventListener("mousedown",Re,b),window.addEventListener("keydown",Ee,b),window.addEventListener("scroll",Ce,b),j=!0,window.performance.getEntriesByType("navigation").map(e=>e.type).includes("reload")&<({url:window.location.href,currentPageTitle:document.title}),window.performance.getEntriesByType("navigation").map(e=>e.type).includes("back_forward")&&pt({curUrl:window.location.href,fromUrl:document.referrer,currentPageTitle:document.title}))},w={isRecording:!1,scrollEventUuids:{},stopRecording:()=>{}},Pe=()=>window.indexedDB&&window.IDBKeyRange&&window.CompressionStream,f=(()=>{const e=s.sessionStorageHelper.getItem("sprig.sessionId");if(e)return s.breadcrumbsLogger.info("SessionIDFound",{savedSessionId:e}),s.sessionStorageHelper.removeItem("sprig.sessionId"),e;const t=s.v4();return s.breadcrumbsLogger.info("GeneratedSessionID",{uuid:t}),t})(),te=()=>{s.sessionStorageHelper.setItem("sprig.disableReplayRecording","disabled")},S=()=>!!s.sessionStorageHelper.getItem("sprig.disableReplayRecording");window.addEventListener("beforeunload",()=>{s.breadcrumbsLogger.info("BeforeUnload",{sessionId:f}),s.sessionStorageHelper.setItem("sprig.sessionId",f)});const ie=e=>e&&e.trim().substring(0,500).replace(/\s\s+/g," ").replace(/\r?\n|\r/g," ").substring(0,250),v=(e,t)=>{var r,n;if(!S()&&w.isRecording)try{(n=(r=window.rrwebRecord)==null?void 0:r.addCustomEvent)==null||n.call(r,e,t)}catch(a){G("Error recording custom event",a)}},ut=e=>{var t;(t=e==null?void 0:e.elementAttributes)!=null&&t.text&&(e.elementAttributes.text=ie(e.elementAttributes.text)),v("Sprig_Click",e)},lt=e=>{v("Sprig_Refresh",e)},pt=e=>{e.currentPageTitle&&(e.currentPageTitle=ie(e.currentPageTitle)),v("Sprig_BackForward",e)},gt=e=>{v("Sprig_Keystroke",e)},mt=async e=>{const{x:t,xPath:r,y:n}=e,a=w.scrollEventUuids[r];if(a)return h(async()=>{var c,d,u,y;const o=await l.openDB(),i=await o.get("events",a);if(i!=null&&i.event){const p=JSON.parse(i.event),m=t>((d=(c=p.data)==null?void 0:c.payload)==null?void 0:d.x),g=n>((y=(u=p.data)==null?void 0:u.payload)==null?void 0:y.y);if(!m&&!g)return null;m&&(p.data.payload.x=t),g&&(p.data.payload.y=n),p.data.payload.elementAttributes=e.elementAttributes,i.event=JSON.stringify(p),await o.put("events",i)}else v("Sprig_Scroll",e)},"Error updating scroll event");v("Sprig_Scroll",e)},xe=()=>{w.stopRecording&&(w.stopRecording(),w.stopRecording=void 0),w.isRecording=!1,["cleanupInterval","inactivityInterval","pendingCheckInterval"].forEach(e=>{w[e]&&(clearInterval(w[e]),w[e]=void 0)}),j&&(window.removeEventListener("click",ke,b),window.removeEventListener("pointerdown",Ue,b),window.removeEventListener("mousedown",Re,b),window.removeEventListener("keydown",Ee,b),window.removeEventListener("scroll",Ce,b),j=!1)},wt=["did not allow mutations","called in an invalid security context"],yt=(e,t,{reportError:r=!0,extraInfo:n={}})=>{if(!S()&&t instanceof Error){if(te(),t.name==="VersionError")return s.breadcrumbsLogger.error("VersionErr",{message:e}),l.deleteDB();(a=>{if(!a)return!0;for(const o of wt)if(a.toLowerCase().includes(o))return!1;return!0})(t==null?void 0:t.message)&&(r&&window.UserLeap.reportError(e,t,n),l.clearAll())}},G=(e,t,{reportError:r}={reportError:!0})=>{xe(),s.breadcrumbsLogger.error("ReplayErr",{code:t.code,name:t.name}),yt(e,t,{reportError:r})},h=async(e,t)=>{try{return await e()}catch(r){G(t,r)}};Pe()&&(Z("replayStorage").catch(console.error),Z("sprig.replay").catch(console.error));const l=new class{openDB(){return function(e,t,{blocked:r,upgrade:n,blocking:a,terminated:o}={}){const i=indexedDB.open(e,t),c=R(i);return n&&(i.onupgradeneeded=d=>{n(R(i.result),d.oldVersion,d.newVersion,R(i.transaction),d)}),r&&(i.onblocked=d=>r(d.oldVersion,d.newVersion,d)),c.then(d=>{o&&(d.onclose=()=>o()),a&&(d.onversionchange=u=>a(u.oldVersion,u.newVersion,u))}).catch(()=>{}),c}("sprigReplay",1,{upgrade:(e,t,r)=>{if(r===0&&s.sessionStorageHelper.setItem("sprig.pendingCount","0"),!e.objectStoreNames.contains("events")){const n=e.createObjectStore("events",{keyPath:"uuid"});n.createIndex("sessionId","sessionId"),n.createIndex("timestamp","timestamp"),n.createIndex("[sessionId+timestamp]",["sessionId","timestamp"])}if(!e.objectStoreNames.contains("chunkUploads")){const n=e.createObjectStore("chunkUploads",{keyPath:"uuid"});n.createIndex("sessionId","sessionId"),n.createIndex("timestamp","timestamp"),n.createIndex("[sessionId+status]",["sessionId","status"]),n.createIndex("[uploadId+status]",["uploadId","status"]),n.createIndex("[sessionId+status+uploadId]",["sessionId","status","uploadId"])}if(!e.objectStoreNames.contains("pendingCaptures")){const n=e.createObjectStore("pendingCaptures",{keyPath:"uuid"});n.createIndex("sessionId","sessionId"),n.createIndex("timestamp","timestamp"),n.createIndex("[sessionId+targetTimestamp]",["sessionId","targetTimestamp"])}}})}deleteDB(){return Z("sprigReplay").catch(console.error)}async bulkAdd(e,t){const r=(await this.openDB()).transaction(e,"readwrite");return Promise.all([...t.map(n=>r.store.add(n)),r.done])}async clearAll(){const e=(await this.openDB()).transaction(["events","chunkUploads","pendingCaptures"],"readwrite");return Promise.all([e.objectStore("events").clear(),e.objectStore("chunkUploads").clear(),e.objectStore("pendingCaptures").clear()])}async deleteBySessionId(e,t){const r=IDBKeyRange.only(t),n=(await this.openDB()).transaction(e,"readwrite"),a=n.store.index("sessionId");for await(const o of a.iterate(r))await o.delete();await n.done}async updatePartial(e,t,r){const n=(await this.openDB()).transaction(e,"readwrite"),a=await n.store.get(t);a&&await n.store.put({...a,...r}),await n.done}async deleteRowsBefore(e,t,r=()=>!0){const n=IDBKeyRange.upperBound(t,!0),a=(await this.openDB()).transaction(e,"readwrite"),o=a.store.index("timestamp");for await(const i of o.iterate(n))r(i.value)&&await i.delete();await a.done}async getEventsBetween(e,t=Date.now()){if(e>=t)return Promise.resolve([]);const r=IDBKeyRange.bound([f,e],[f,t],!1,!0);return(await this.openDB()).getAllFromIndex("events","[sessionId+timestamp]",r)}async updateEventsExpiredAt(e,t,r=30){const n=new Date,a=n.setMinutes(n.getMinutes()+(r??30)),o=(await this.openDB()).transaction("events","readwrite"),i=o.store.index("[sessionId+timestamp]"),c=IDBKeyRange.bound([f,e],[f,t],!1,!0);for await(const d of i.iterate(c))await d.update({...d.value,expiredAt:a});await o.done}async deleteChunkUploads(e,t){const r=IDBKeyRange.only([t,e]),n=(await this.openDB()).transaction("chunkUploads","readwrite");let o=await n.store.index("[uploadId+status]").openCursor(r);for(;o;)o.delete(),o=await o.continue();await n.done}async getChunkUploadsByStatus({sessionId:e,status:t,uploadId:r}){const n=(await this.openDB()).transaction("chunkUploads","readonly"),a=r?n.store.index("[uploadId+status]"):n.store.index("[sessionId+status]"),o=r?IDBKeyRange.only([r,t]):IDBKeyRange.only([e,t]);return a.getAll(o)}async getPendingCaptures(e={}){return(await(await this.openDB()).getAllFromIndex("pendingCaptures","sessionId",f)).filter(r=>!e.beforePresent||r.targetTimestamp<Date.now()).filter(r=>!e.isBeforeType||r.captureParams.replayParams.replayDurationType==="before").filter(r=>!e.isHeatmap||(r.captureParams.isHeatmap??!1))}async markPendingCaptureToCanUpload(e){const t=(await this.openDB()).transaction("pendingCaptures","readwrite"),r=t.store.index("sessionId");for await(const n of r.iterate(f)){const a=n.value;a.captureParams.responseGroupId===e&&await n.update({...a,canUpload:!0})}await t.done}async markPendingHeatmapsReady(e){if(parseInt(s.sessionStorageHelper.getItem("sprig.pendingCount")??"0")===0)return null;const t=Date.now(),r=(await this.openDB()).transaction("pendingCaptures","readwrite"),n=r.store.index("sessionId");for await(const a of n.iterate(f)){const o=a.value;!o.captureParams.isHeatmap||e&&!e.includes(o.uuid)||await a.update({...o,targetTimestamp:t,captureParams:{...o.captureParams,triggerTimestamp:t,replayParams:{...o.captureParams.replayParams,replayDurationSeconds:Math.floor((t-o.timestamp)/1e3)}}})}await r.done}},E=[];let M,Be,V,Le,H,Te,P=[],L=!1,B=0,O=!1,Me=!1,de=[],J=!1;const T=()=>O&&!L&&Date.now()<=V,ft=({apiUrl:e,config:t,triggerSnapshot:r,forceInit:n=!1})=>{O&&!n||(s.sessionStorageHelper.isStorageAvailable?(P=[],de.splice(0),E.splice(0),B=0,H=r,Be=e,M={responseGroupUuid:t.responseGroupUuid,surveyId:t.surveyId,userAgent:t.userAgent,sdkVersion:t.sdkVersion},Le=t.maxDurationSeconds,vt(),O||(Te=window.setInterval(bt,500)),O=!0):L=!0)},ht=[D.Drag,D.Input,D.MediaInteraction,D.MouseInteraction,D.MouseMove,D.Scroll,D.Selection,D.TouchMove],It=e=>e.type===k.Custom||e.type===k.IncrementalSnapshot&&ht.includes(e.data.source),ce=e=>e.some(It),bt=async()=>{if(!T())return void window.clearInterval(Te);if(Ae(),!ce(E))return;const e=E[0].timestamp;Date.now()-e>35e3&&(H==null||H())},Ae=async()=>{if(P.length||J)return;J=!0;const e=await Dt();if(!e)return void(L=!0);de.splice(0,e.length).forEach(t=>t(e.shift())),e.forEach(t=>P.push(t)),J=!1},vt=()=>{const e=s.sessionStorageHelper.getItem("sprig.alwayson.info");if(e){s.breadcrumbsLogger.info("Read stored session state",e);const t=JSON.parse(e);L=t.disabled,M=t.metadata,P=t.uploadUrls,B=t.currentIndex,V=t.expirationTimestamp,t.pendingEventTimestamp&&(s.breadcrumbsLogger.info(`Uploading with pending timestamp: ${t.pendingEventTimestamp}`),St(t.pendingEventTimestamp))}else V=1e3*Le+Date.now()},St=async e=>{const t=Date.now(),r=(await l.getEventsBetween(e,t)).map(a=>JSON.parse(a.event));if(!ce(r))return;Oe(r);const n=await He();n&&await Ne(n,r)},_e=async(e,t)=>{try{const r=await e();if(!r.ok)throw new Error(`Error ${t}`);return r}catch{L=!0}},Ne=async(e,t)=>{if(!T()||!e)return;const r=await(async n=>{const a=new TextEncoder,o=new CompressionStream("gzip"),i=o.writable.getWriter(),c=a.encode(JSON.stringify(n));return i.write(c),i.close(),new Uint8Array(await new Response(o.readable).arrayBuffer())})(t);s.breadcrumbsLogger.info("Uploading always-on events with presigned url"),await _e(()=>s.sprigFetch(e,{body:r,method:"PUT"}),"uploading always-on with presigned url")},Dt=async()=>{if(!T())return;const{surveyId:e,responseGroupUuid:t}=M,r={responseGroupUuid:t,surveyId:e,index:B+1};s.breadcrumbsLogger.info("Fetching always-on upload urls",r);const n=await _e(()=>s.sprigFetch(`${Be}/sdk/1/replayUrls`,{method:"POST",body:JSON.stringify(r),headers:s.getHttpHeaders(window.UserLeap)}),"fetching always-on signed urls");if(!n)return;const a=n.json.signedUrls;return s.breadcrumbsLogger.info("Fetched more always-on upload urls",{body:r,urls:a}),a},He=async()=>{if(P.length)return P.shift();const e=new Promise(t=>{de.push(t)});return Ae(),e},Oe=e=>{var a,o,i;const t=e.length?e[e.length-1].timestamp:Date.now(),r=B,n=((o=(a=window.UserLeap)==null?void 0:a.config)==null?void 0:o.customMetadata)??((i=window.__cfg)==null?void 0:i.customMetadata);B++,e.push({timestamp:t,type:k.Custom,data:{tag:"Sprig_Meta",payload:{...M,index:r,visitorId:window.UserLeap.visitorId??"",timestamp:t,customMetadata:n}}})},Et=(e,t)=>{T()&&!Me&&(e||E.length)&&(e&&E.length&&(async()=>{const r=E.splice(0);if(!ce(r))return;s.breadcrumbsLogger.info("Capturing always-on event array to upload"),Oe(r);const n=await He();n&&await Ne(n,r)})(),E.push(t))};window.addEventListener("beforeunload",async()=>{Me=!0,T()&&(s.breadcrumbsLogger.info("Always On handle page unload"),(()=>{let e;E.length&&(e=E[0].timestamp);const t={disabled:L,metadata:M,uploadUrls:P,currentIndex:B,pendingEventTimestamp:e,expirationTimestamp:V};s.breadcrumbsLogger.info("Storing session state on unload",t),s.sessionStorageHelper.setItem("sprig.alwayson.info",JSON.stringify(t))})())});const Fe=async(e,t)=>{const r=performance.now();let n;try{n=await e()}finally{const a=performance.now()-r;let o=s.PerformanceMetrics[t];o||(o=s.registerMetric(t)),o.report(a/1e3)}return n},je=(e,t)=>{const r=performance.now();try{e()}finally{const n=performance.now()-r;let a=s.PerformanceMetrics[t];a||(a=s.registerMetric(t)),a.report(n/1e3)}};let Ve=5e3,re=6e4,ne=0,U,ae=!1,oe=[];const Ct=e=>{var t,r,n,a;if((t=e.event)!=null&&t.includes("Sprig_Scroll")){const o=(a=(n=(r=JSON.parse(e.event))==null?void 0:r.data)==null?void 0:n.payload)==null?void 0:a.xPath;if(!o)return;w.scrollEventUuids[o]=e.uuid}oe.push(e),ae||kt()},kt=()=>{ae=!0,setTimeout(async()=>{if(S())return;const e=oe;oe=[],ae=!1,je(async()=>{await(async t=>{const r=t.map(n=>({...n,sessionId:n.sessionId??f}));if(r.length!==0)return h(()=>l.bulkAdd("events",r),"Error storing replay events")})(e)},"sdk_replay_add_event_batch_seconds")},500)},Rt=(e,t,r)=>{w.cleanupInterval=window.setInterval(()=>{const n=Date.now();Fe(()=>h(async()=>{S()||await Promise.all([l.deleteRowsBefore("events",n-1e3*e,a=>a.expiredAt===void 0||a.expiredAt<n-1e3*e),l.deleteRowsBefore("chunkUploads",n-1e3*t),l.deleteRowsBefore("pendingCaptures",n-1e3*r,a=>!a.canUpload)])},"Error deleting table rows"),"sdk_replay_cleanup_seconds"),s.breadcrumbsLogger.debug("CleanupComplete")},3e4)},Ut=()=>{w.pendingCheckInterval=window.setInterval(async()=>{h(async()=>{await se()},"Error initiating pending captures")},5e3)};let q=!1;const se=async(e=!1)=>{if(!q)try{q=!0;const t=parseInt(U??"0");if(t===0)return;const r=await l.getPendingCaptures({beforePresent:!0,isBeforeType:e}),n=await l.openDB();await Promise.all(r.map(async a=>(await n.delete("pendingCaptures",a.uuid),Ke(a.captureParams,a.canUpload)))),U=(t-r.length).toString(),s.sessionStorageHelper.setItem("sprig.pendingCount",U)}finally{q=!1}},Pt=async(e,t,r,n,a)=>{const o=Math.min(e+a,r),i=await Fe(()=>l.getEventsBetween(e,o),"sdk_replay_get_events_between_seconds");if(!(i!=null&&i.length))return s.breadcrumbsLogger.debug("NoEventsFound"),{validStartFound:n,events:[]};if(!n){s.breadcrumbsLogger.debug("ValidStartSearch");let c=-1;return i==null||i.forEach((d,u)=>{if(!d.isValidStart)return;const y=d.timestamp<=t;(c<0||y)&&(c=u)}),c<0?(s.breadcrumbsLogger.debug("ValidStartNotFound"),{validStartFound:n,events:[]}):{validStartFound:!0,events:i==null?void 0:i.slice(c)}}return{validStartFound:n,events:i}},Ge=e=>Promise.all(e.map(async t=>{const r=await(async n=>be.execute(async()=>{var i;s.breadcrumbsLogger.info("UploadChunkStart",{chunkIndex:n.chunkIndex,surveyId:n.surveyId});const a=await s.sprigFetch(n.uploadUrl,{body:n.data,method:"PUT"});s.breadcrumbsLogger.http("UploadChunkEnd",{url:n.uploadUrl,method:"PUT",status_code:a.status,reason:a.statusText??"OK",chunkIndex:n.chunkIndex,surveyId:n.surveyId});const o=(i=a.headers)==null?void 0:i.get("ETag");if(!o)throw new Error(`Upload response did not include etag for upload ${n.uploadId}, part ${n.chunkIndex}`);return o}))(t);return await l.updatePartial("chunkUploads",t.uuid,{data:null,etag:r,status:"UploadComplete"}),t.uploadId})),$e=async e=>{const t=await l.getChunkUploadsByStatus({status:"UploadComplete",uploadId:e});if(!(t!=null&&t.length))return void s.breadcrumbsLogger.info("NoChunksForUpload",{uploadId:e});const r=t.reduce((o,i)=>(o.find(c=>c.chunkIndex===i.chunkIndex)||o.push(i),o),[]);r.sort((o,i)=>o.chunkIndex-i.chunkIndex);const n=r.map(o=>({ETag:o.etag,PartNumber:o.chunkIndex})).filter(o=>o.ETag!==null),a=r[0];await ve({apiUrl:a.apiUrl,surveyId:a.surveyId,uploadId:e,responseGroupUuid:a.responseGroupId,etags:n,headers:a.completeUploadHeaders,replayDuration:a.replayDuration}),await l.deleteChunkUploads("UploadComplete",e)},xt=()=>{h(async()=>{const e=await l.getChunkUploadsByStatus({sessionId:f,status:"ReadyForUpload"});if(!(e!=null&&e.length))return;const t=await Ge(e);t!=null&&t.length&&await Promise.all(t.map(r=>{if(r)return $e(r)}))},"Error uploading unfinished chunks")},Bt=async(e,t)=>{const r=t??Date.now();return(async(n,a)=>{const o=new TextEncoder;let i=null;const c=new CompressionStream("gzip"),d=c.writable.getWriter();let u=!1,y=!1,[p,m]=[0,0],g=[];for(let C=n-35e3;C<a;C+=re){if({validStartFound:y,events:g}=await Pt(C,n,a,y,re),!(g!=null&&g.length)){s.breadcrumbsLogger.debug("NoEventsFound");continue}p===0&&(p=g[0].timestamp),m=g[g.length-1].timestamp;const A=g.map(x=>x.event);A.push(`{"timestamp":${a}}`);const _=`${u?",":"["}${A}`,N=o.encode(_);je(()=>{d.write(N)},"sdk_replay_compression_seconds"),u=!0}if(m-p<Ve)return s.breadcrumbsLogger.debug("ReplayTooShort"),null;const I=o.encode("]");return d.write(I),d.close(),i=new Uint8Array(await new Response(c.readable).arrayBuffer()),i})(r-e,r)},fe=async e=>{const{surveyId:t,responseGroupId:r,visitorId:n,apiUrl:a,completeUploadHeaders:o,replayParams:i,triggerTimestamp:c}=e,d=await Bt(1e3*i.replayDurationSeconds,c);if(!(d!=null&&d.length))return void s.breadcrumbsLogger.info("FileDataEmpty",{surveyId:t});const u=((p,m,g)=>{const I=p.length,C=1024*m*1024,A=Math.ceil(I/g),_=Math.max(C,A),N=[];let x=0;for(;x<I;)N.push(p.slice(x,x+_)),x+=_;return N})(d,i.minimumChunkSizeMb,i.signedUrls.length),y=await Promise.all(u.map(async(p,m)=>{const g=s.v4(),I={apiUrl:a,chunkIndex:m+1,completeUploadHeaders:o,etag:null,responseGroupId:r,status:"ReadyForUpload",surveyId:t,timestamp:c,totalChunks:u.length,data:p,uploadId:i.uploadId,uploadUrl:i.signedUrls[m].url,uuid:g,visitorId:n};return await(await l.openDB()).add("chunkUploads",{...I,sessionId:I.sessionId??f}),I}));await(async(p,m)=>{await Ge(m),await Promise.all(p.map(g=>$e(g)))})([i.uploadId],y)},Ke=async(e,t)=>{if(S())return s.breadcrumbsLogger.debug("ReplayDisabled-ScheduleOrCapture");const{isHeatmap:r,isStandalone:n,replayParams:a,triggerTimestamp:o,responseGroupId:i}=e,c=async()=>{setTimeout(()=>s.eventEmitter.removeListener(s.SprigEvent.QuestionAnswered,c),0),h(async()=>{a.replayDurationType==="before"?await fe(e):await l.markPendingCaptureToCanUpload(i)},"Error in schedule/capture callback")};h(async()=>{if(a.replayDurationType==="after"||a.replayDurationType==="beforeAndAfter")return!n&&!r&&s.eventEmitter.on(s.SprigEvent.QuestionAnswered,c),void await Je(e);if(n||r||t)await fe(e),r&&Lt();else{const d=35+a.replayDurationSeconds,u=o-1e3*d,y=o;await l.updateEventsExpiredAt(u,y,a.expirationTimeLimitMinutes),s.eventEmitter.on(s.SprigEvent.QuestionAnswered,c)}},"Error in scheduling/capturing replay")},Lt=async()=>{parseInt(U??"0")||s.sessionStorageHelper.removeItem("sprig.isCapturingHeatmap"),s.sessionStorageHelper.getItem("sprig.teardownAfterCapture")&&(xe(),We(),s.sessionStorageHelper.removeItem("sprig.teardownAfterCapture"))},We=async()=>S()?s.breadcrumbsLogger.debug("ReplayDisabled-ClearData"):Promise.all([l.deleteBySessionId("events",f),l.deleteBySessionId("pendingCaptures",f)]).catch(e=>{G("Error clearing user replay data",e)}),Je=async e=>{if(S())return;const{isHeatmap:t,surveyId:r}=e,n=await l.getPendingCaptures(),a=n==null?void 0:n.filter(d=>d.captureParams.surveyId===r);if(a!=null&&a.length)return void s.breadcrumbsLogger.info("PendingCaptureExists",{surveyId:r});t&&(w.isRecording&&h(()=>{var d,u;return(u=(d=window.rrwebRecord)==null?void 0:d.takeFullSnapshot)==null?void 0:u.call(d,!0)},"Error recording full snapshot"),s.sessionStorageHelper.setItem("sprig.isCapturingHeatmap","true"),ne=Date.now(),w.inactivityInterval||(w.inactivityInterval=window.setInterval(()=>{var d;d=ne,Date.now()-d>=3e4&&h(()=>l.markPendingHeatmapsReady(),"Error in heatmap inactivity")},1e3)));const o={...e,replayParams:{...e.replayParams}};e.replayParams.replayDurationType==="beforeAndAfter"&&(o.replayParams.replayDurationSeconds*=2),o.replayParams.replayDurationType="before";const i=e.triggerTimestamp+1e3*e.replayParams.replayDurationSeconds;o.triggerTimestamp=i,U=(parseInt(U??"0")+1).toString(),s.sessionStorageHelper.setItem("sprig.pendingCount",U),await(await l.openDB()).add("pendingCaptures",{canUpload:!1,captureParams:o,sessionId:f,targetTimestamp:i,timestamp:Date.now(),uuid:s.v4()})},Tt=Object.freeze(Object.defineProperty({__proto__:null,RecordEvent:e=>{v("Sprig_TrackEvent",e)},RecordPageView:e=>{e.description&&(e.description=ie(e.description)),v("Sprig_PageView",e)},RecordSurveyShown:e=>{v("Sprig_ShowSurvey",e)},_completeSessionReplay:async({surveyId:e,responseGroupUuid:t,eventDigest:r,headers:n})=>{if(!e||!t)return!1;const a=window.UserLeap._API_URL,o=await ve({surveyId:e,responseGroupUuid:t,eventDigest:r,apiUrl:a,headers:n},!0);return!(o!=null&&o.error)},checkPendingHeatmapsUrl:()=>S()?s.breadcrumbsLogger.debug("ReplayDisabled-PendingHeatmaps"):h(async()=>{const e=(await l.getPendingCaptures({isHeatmap:!0})).map(t=>({eventId:t.captureParams.eventId,uuid:t.uuid})).filter(({eventId:t})=>!s.checkUrlStillMatching(t)).map(({uuid:t})=>t);return s.breadcrumbsLogger.info("PendingHeatmapsToComplete",{count:e.length}),e.length&&(await l.markPendingHeatmapsReady(e),s.breadcrumbsLogger.info("MarkedPendingHeatmapsReady")),e.length},"Error marking pending heatmaps ready"),clearUserReplayData:We,disableRecording:G,initializeReplay:async({maxReplayDurationSeconds:e,maxInflightRequests:t=2,replaySettings:r,teardownAfter:n=!1,apiUrl:a,alwaysOnConfig:o})=>{if(o&&ft({apiUrl:a,config:o,triggerSnapshot:()=>{var d;return(d=window.rrwebRecord)==null?void 0:d.takeFullSnapshot(!0)}}),U=s.sessionStorageHelper.getItem("sprig.pendingCount"),w.isRecording)return;if(n&&s.sessionStorageHelper.setItem("sprig.teardownAfterCapture","true"),S())return s.breadcrumbsLogger.debug("ReplayDisabled");if(await(async()=>{var d;if(!Pe())return!0;if((d=window.navigator.storage)!=null&&d.estimate)try{const{quota:u=0,usage:y=0}=await window.navigator.storage.estimate(),p=(u-y)/1024**3;return s.breadcrumbsLogger.info("Storage",{availableGb:p}),p<.5}catch{return!0}return!1})())return s.breadcrumbsLogger.debug("IDBNotSupported"),te();try{const d=await l.openDB();s.breadcrumbsLogger.info("DBVersion",{version:d.version})}catch(d){return s.breadcrumbsLogger.error("ReplayOpenErr",{name:d.name}),d.name==="VersionError"&&l.deleteDB(),te()}h(async()=>{await se(!0)},"Error uploading ready pending captures");const i=T()?30:0,c=Math.max(e??0,i);if(!c)return s.breadcrumbsLogger.debug("MissingDuration");s.breadcrumbsLogger.debug("ReplayInit"),await h(async()=>{var d;if(r!=null&&r.minDuration&&(Ve=r.minDuration),r!=null&&r.batchDuration&&(re=r.batchDuration),d=t,be.setLimit(d),xt(),Rt(c+35,1800,c+35),Ut(),!window.rrwebRecord){const{record:m}=await import(window.UserLeap.replayLibraryURL??"https://cdn.sprig.com/dependencies/record-2.0.0-alpha.17.min.js");window.rrwebRecord=m}const u=window.rrwebRecord;if(!u)return s.breadcrumbsLogger.error("RecordScriptFailed");let y=!0,p=0;w.stopRecording=u({checkoutEveryNms:3e4,sampling:{input:"last",scroll:250,media:800},emit:(m,g)=>{if(m.type===k.Custom&&(ne=Date.now()),S())return;if(g&&m.type===k.Meta)p=performance.now();else if(g&&p&&m.type===k.FullSnapshot){const C=performance.now()-p;s.reportAndRegister("sdk_replay_snapshot_seconds",C/1e3)}const I=y||!!g&&m.type===k.Meta;y=!1,Et(I,m),Ct({uuid:s.v4(),event:JSON.stringify(m),isValidStart:I,timestamp:Date.now()})},...r}),w.isRecording=!!w.stopRecording,w.isRecording&&(s.eventEmitter.on("survey.complete",m=>{var g;g={id:m,userAgent:window.navigator.userAgent},v("Sprig_SubmitSurvey",g)}),ct())},"Error initializing replay")},isReplayRecording:()=>w.isRecording,scheduleCapture:Je,scheduleOrCaptureReplay:Ke,tryReplayAction:h,uploadReadyPendingCaptures:se},Symbol.toStringTag,{value:"Module"}));s.registerReplay(Tt);