UNPKG

@sprig-technologies/sprig-browser

Version:

npm package for the sprig web sdk

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