@espejo/browser 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -526,4 +526,4 @@ textarea:focus-visible {
526
526
  <p class="ef-title" id="ef-title">${o.title}</p>
527
527
  <div class="ef-options" id="ef-options" role="group" aria-label="${o.title}" data-kind="${t.kind}">${l}</div>
528
528
  <p class="ef-thanks" id="ef-thanks" role="status" aria-live="polite" hidden>${o.thanks}</p>
529
- </div>`;let p=i.querySelector(".ef-root"),u=i.getElementById("ef-close"),c=i.getElementById("ef-title"),h=i.getElementById("ef-options"),w=i.getElementById("ef-thanks"),x=Array.from(h.querySelectorAll(".ef-opt")),m=!1,b=null,A=()=>{b!==null&&(e.defaultView?.clearTimeout(b),b=null)},k=()=>{A(),e.removeEventListener("keydown",R,!0),a.remove()},N=g=>{if(!m){m=!0;for(let B of x)B.disabled=!0;n(g).catch(()=>{}),c.hidden=!0,h.hidden=!0,w.hidden=!1,b=e.defaultView?.setTimeout(k,1600)??null}},R=g=>{g.key==="Escape"&&(g.stopPropagation(),k())},j=g=>{let B=g.currentTarget??null;B&&N(Number(B.dataset.value))};for(let g of x)g.addEventListener("click",j);u.addEventListener("click",k);let v=ke(p);return e.addEventListener("keydown",R,!0),e.body.appendChild(a),{destroy(){A();for(let g of x)g.removeEventListener("click",j);u.removeEventListener("click",k),v(),e.removeEventListener("keydown",R,!0),a.remove()},shadowRootForTesting:i}}var Co="espejo:feedback:lastShown:";function rn(e){return`${Co}${e}`}function Se(e,t,n){try{let o=sn(n);if(!o)return!0;let r=o.getItem(rn(e));if(!r)return!0;let a=Number(r);return Number.isFinite(a)?Date.now()-a>=t*864e5:!0}catch{return!0}}function _e(e,t){try{sn(t)?.setItem(rn(e),String(Date.now()))}catch{}}function sn(e){return(e?.defaultView??(typeof window<"u"?window:void 0))?.localStorage??null}var Lo="__espejoInstallAnnotator";function an(e,t=document){return ye(e,"espejo.draw.js",Lo,t)}var dn="@espejo/browser",cn="0.1.0",Mo="https://app.espejo.dev",ln={source:"manual"},Te=class{constructor(t){this.recorder=null;this.uninstall=[];this.dom=null;this.routeSnapshot=null;this.snapshotFn=null;this.widget=null;this.lastReport=null;this.feedback=null;this.annotator=null;this.markupHost=null;this.video=null;this.videoBlob=null;this.videoContentType="video/webm";this.videoHasAudio=!1;this.videoMs=0;this.autoConfig=null;this.autoGuard=null;this.autoKilled=!1;this.autoInFlight=!1;this.triggerSink=null;this.triggerBuf=[];this.triggersStop=null;if(!t?.key)throw new Error("Espejo: missing data-key (the project's public key)");this.config={...t,ingestUrl:t.ingestUrl||Mo,mode:t.mode||"ring"},this.pristineFetch=typeof globalThis.fetch=="function"?globalThis.fetch.bind(globalThis):void 0}get recording(){return this.recorder!==null}start(){if(this.recorder)return;let t=new V(this.config.budgets);this.recorder=t,this.autoKilled=this.config.autoReport==="off",this.config.capture==="dom"&&(this.routeSnapshot=qt({ingestUrl:this.config.ingestUrl,key:this.config.key,getSnapshot:()=>this.snapshotFn,fetchImpl:this.pristineFetch})),this.uninstall=[Ht(t,{ignoreOrigins:[this.config.ingestUrl],onEntry:n=>this.onNetworkEntry(n)}),Ft(t,{onEntry:(n,o)=>this.onConsoleEntry(n,o)}),Ut(t,{onEntry:(n,o)=>this.pushTriggerSignal({kind:n,tMs:o})}),$t(t,n=>{this.routeSnapshot?.onRoute(),this.pushTriggerSignal({kind:"nav",tMs:t.elapsed(),url:n})})],this.config.capture==="dom"&&this.enableDom(t),this.config.button!=="off"&&(this.widget=nn({report:(n,o)=>this.report(n,ln,o),text:this.config.buttonText,theme:this.config.theme,position:this.config.position,icon:this.config.buttonIcon,video:{supported:()=>K(),start:n=>this.startVideo(n),setMicrophone:n=>this.setMicrophone(n),stop:async()=>{await this.stopVideo()},discard:()=>this.discardVideo(),setMarkup:(n,o)=>this.setMarkup(n,o),limitSeconds:240}})),this.loadAutoReport(),this.config.feedback!=="off"&&this.loadFeedback()}pushTriggerSignal(t){try{this.triggerSink?this.triggerSink(t):this.triggerBuf.length<300&&this.triggerBuf.push(t)}catch{}}async loadTriggers(){if(!this.recorder||this.triggersStop)return;let t=await ye(this.config.ingestUrl,"espejo.triggers.js",Yt);if(!(!t||!this.recorder||this.triggersStop))try{let n=t({ingestUrl:this.config.ingestUrl,key:this.config.key,fetchImpl:this.pristineFetch,now:()=>this.recorder?.elapsed()??0,subscribe:o=>{this.triggerSink=o;for(let r of this.triggerBuf.splice(0))o(r)},theme:this.config.theme});n&&(this.triggersStop=n.stop)}catch{}}async loadFeedback(){let t=await ge(this.config.ingestUrl,this.config.key,this.pristineFetch);t?.enabled&&(!this.recorder||this.feedback||Se(this.config.key,t.cadence_days)&&(_e(this.config.key),this.feedback=Ee({config:t,vote:n=>ve({ingestUrl:this.config.ingestUrl,key:this.config.key,kind:t.kind,value:n,pageHost:typeof location<"u"?location.host:void 0,userRef:this.config.userRef},this.pristineFetch),text:this.config.feedbackText,theme:this.config.theme})))}async loadAutoReport(){let{config:t,videoSurface:n,hasTriggers:o}=await me(this.config.ingestUrl,this.config.key,this.pristineFetch);n&&(this.config.videoSurface=n),o&&this.loadTriggers(),t&&(this.autoConfig=t,this.autoGuard=new Lt(t))}setAutoReport(t){this.autoKilled=!t}identify(t){this.config.userRef=t||void 0}canOpenReport(){return!!this.widget&&!this.video}openReport(){let t=this.canOpenReport();return t&&this.widget.open(),t}get lastReportId(){return this.lastReport}get autoReportActive(){return!!this.autoConfig&&!this.autoKilled}autoEnabled(t){return this.autoKilled||!this.autoConfig||!this.recorder?!1:this.autoConfig.triggers.includes(t)}onConsoleEntry(t,n){if(n==="console"&&t.level!=="error")return;this.pushTriggerSignal({kind:"console_error",tMs:this.recorder?.elapsed()??0});let o=n==="window_error"?"auto:uncaught":n==="unhandled_rejection"?"auto:unhandled_rejection":"auto:console_error";this.maybeAutoReport(o,Ue(o,t.text,t.stack))}onNetworkEntry(t){let n=Mt(t.status,!!t.error);n&&(this.pushTriggerSignal({kind:"http_error",tMs:this.recorder?.elapsed()??0}),this.maybeAutoReport(n,Ue(n,`${t.method} ${t.url}`,String(t.status??t.error))))}maybeAutoReport(t,n){try{if(!this.autoEnabled(t)||this.autoInFlight||!this.autoGuard?.check(n).allowed)return;this.autoInFlight=!0,this.report(void 0,{source:"auto",trigger:t}).catch(()=>{}).finally(()=>{this.autoInFlight=!1})}catch{this.autoInFlight=!1}}async enableDom(t){let n=this.config.rrwebRecord??await Gt();if(!n||this.recorder!==t)return;this.dom=Wt(t,n);let o=this.config.rrwebSnapshot??await Vt();this.recorder===t&&(this.snapshotFn=o,o&&this.routeSnapshot?.onRoute())}stop(){for(let t of this.uninstall.splice(0))try{t()}catch{}this.dom?.stop(),this.dom=null,this.routeSnapshot?.stop(),this.routeSnapshot=null,this.snapshotFn=null,this.widget?.destroy(),this.widget=null,this.feedback?.destroy(),this.feedback=null;try{this.triggersStop?.()}catch{}this.triggersStop=null,this.triggerSink=null,this.triggerBuf=[],this.teardownMarkup(),this.recorder=null}async startVideo(t={}){if(!K())throw new Error("This browser can't record the screen.");this.video||(this.video=await Kt({...t,surface:t.surface??this.config.videoSurface}),this.videoContentType=this.video.contentType)}async setMicrophone(t){return await this.video?.setMicrophone(t)??{on:!1,denied:!1}}get microphoneOn(){return this.video?.microphoneOn??!1}async stopVideo(){return this.video?(this.videoHasAudio=this.video.hasAudio,this.videoBlob=await this.video.stop(),this.videoMs=this.video.durationMs,this.video=null,this.videoBlob):null}get recordingVideo(){return this.video!==null}async setMarkup(t,n=()=>{}){if(!t)return this.teardownMarkup(),!1;if(this.annotator)return!0;if(typeof document>"u")return!1;let o=await an(this.config.ingestUrl);if(!o)return!1;let r=document.createElement("div");r.setAttribute("data-espejo-markup","");let a=r.attachShadow({mode:"closed"});return document.body.appendChild(r),this.markupHost=r,this.annotator=o({root:a,onExit:()=>{this.teardownMarkup(),n()}}),this.annotator?!0:(this.teardownMarkup(),!1)}teardownMarkup(){this.annotator?.destroy(),this.annotator=null,this.markupHost?.remove(),this.markupHost=null}discardVideo(){this.videoBlob=null,this.videoHasAudio=!1,this.videoMs=0}snapshot(){return this.recorder?.snapshot()??null}async report(t,n=ln,o){let r=this.recorder;if(!r)return null;let a=n.source==="auto";this.video&&!a&&await this.stopVideo();let i=r.snapshot(),s=this.dom?.events(),l=!a&&this.videoBlob?{blob:this.videoBlob,contentType:this.videoContentType}:void 0,p=await Jt({ingestUrl:this.config.ingestUrl,key:this.config.key,manifest:this.manifest(r,t,{dom:!!s?.length,video:!!l,audio:!!l&&this.videoHasAudio},n),events:i,dom:s?.length?s:void 0,video:l,onProgress:a?void 0:o},this.pristineFetch);return r.clear(),this.dom?.buffer.clear(),a||(this.videoBlob=null,this.videoHasAudio=!1,this.videoMs=0,this.lastReport=p.session_id),p.url}manifest(t,n,o,r){return{bundle_version:_t,source:"web-sdk",mode:o.video?"video":o.dom?"dom":"events",trigger:r.source==="auto"?r.trigger:this.config.mode==="always"?"always":"manual",report_source:r.source,description:n??null,started_at:t.startedAtIso,duration_ms:t.elapsed(),page:{host:typeof location<"u"?location.host:null,url:typeof location<"u"?T(location.href):null},app:{release:this.config.release??null,env:this.config.env??null},user_ref:this.config.userRef??null,sdk:{name:dn,version:cn},dropped:{...t.dropped,dom_segments:this.dom?.buffer.droppedCount??0},has_dom:o.dom,has_video:o.video,...o.video?{video_ms:this.videoMs}:{},has_audio:o.audio}}};function Io(e={}){if(typeof document>"u")return null;let t=document.currentScript,n=t?.dataset.key;if(!n)return null;let o=new Te({...e,key:n,ingestUrl:t?.dataset.ingest,mode:t?.dataset.mode==="always"?"always":"ring",capture:t?.dataset.capture==="dom"?"dom":e.capture??"events",button:t?.dataset.button==="off"?"off":e.button??"on",autoReport:t?.dataset.autoReport==="off"?"off":e.autoReport??"on",feedback:t?.dataset.feedback==="off"?"off":e.feedback??"on",feedbackText:Do(t?.dataset.feedbackText)??e.feedbackText,theme:Bo(t?.dataset.theme)??e.theme??"auto",position:Oo(t?.dataset.position)??e.position,buttonIcon:t?.dataset.buttonIcon??e.buttonIcon,videoSurface:t?.dataset.videoSurface,release:t?.dataset.release,env:t?.dataset.env,userRef:t?.dataset.userRef??e.userRef});return o.start(),globalThis.espejo=o,o}function Bo(e){return e==="light"||e==="dark"||e==="auto"?e:void 0}function Oo(e){return e==="bottom-right"||e==="bottom-left"||e==="top-right"||e==="top-left"?e:void 0}function Do(e){if(e)try{let t=JSON.parse(e);return t&&typeof t=="object"?t:void 0}catch{return}}0&&(module.exports={BLOCK_ATTRIBUTE,BLOCK_SELECTOR,DEFAULT_BUDGETS,Espejo,FEEDBACK_DEFAULT_TEXT,MASK_SELECTOR,MAX_VIDEO_SECONDS,RingBuffer,SDK_NAME,SDK_VERSION,SegmentRing,SessionRecorder,WIDGET_DEFAULT_TEXT,autoStart,canShowFeedback,fetchAutoReportConfig,fetchFeedbackConfig,installFeedbackWidget,normalizeAutoReportConfig,normalizeFeedbackConfig,sealFeedbackShown,sendVote,videoSupported});
529
+ </div>`;let p=i.querySelector(".ef-root"),u=i.getElementById("ef-close"),c=i.getElementById("ef-title"),h=i.getElementById("ef-options"),w=i.getElementById("ef-thanks"),x=Array.from(h.querySelectorAll(".ef-opt")),m=!1,b=null,A=()=>{b!==null&&(e.defaultView?.clearTimeout(b),b=null)},k=()=>{A(),e.removeEventListener("keydown",R,!0),a.remove()},N=g=>{if(!m){m=!0;for(let B of x)B.disabled=!0;n(g).catch(()=>{}),c.hidden=!0,h.hidden=!0,w.hidden=!1,b=e.defaultView?.setTimeout(k,1600)??null}},R=g=>{g.key==="Escape"&&(g.stopPropagation(),k())},j=g=>{let B=g.currentTarget??null;B&&N(Number(B.dataset.value))};for(let g of x)g.addEventListener("click",j);u.addEventListener("click",k);let v=ke(p);return e.addEventListener("keydown",R,!0),e.body.appendChild(a),{destroy(){A();for(let g of x)g.removeEventListener("click",j);u.removeEventListener("click",k),v(),e.removeEventListener("keydown",R,!0),a.remove()},shadowRootForTesting:i}}var Co="espejo:feedback:lastShown:";function rn(e){return`${Co}${e}`}function Se(e,t,n){try{let o=sn(n);if(!o)return!0;let r=o.getItem(rn(e));if(!r)return!0;let a=Number(r);return Number.isFinite(a)?Date.now()-a>=t*864e5:!0}catch{return!0}}function _e(e,t){try{sn(t)?.setItem(rn(e),String(Date.now()))}catch{}}function sn(e){return(e?.defaultView??(typeof window<"u"?window:void 0))?.localStorage??null}var Lo="__espejoInstallAnnotator";function an(e,t=document){return ye(e,"espejo.draw.js",Lo,t)}var dn="@espejo/browser",cn="0.2.0",Mo="https://app.espejo.dev",ln={source:"manual"},Te=class{constructor(t){this.recorder=null;this.uninstall=[];this.dom=null;this.routeSnapshot=null;this.snapshotFn=null;this.widget=null;this.lastReport=null;this.feedback=null;this.annotator=null;this.markupHost=null;this.video=null;this.videoBlob=null;this.videoContentType="video/webm";this.videoHasAudio=!1;this.videoMs=0;this.autoConfig=null;this.autoGuard=null;this.autoKilled=!1;this.autoInFlight=!1;this.triggerSink=null;this.triggerBuf=[];this.triggersStop=null;if(!t?.key)throw new Error("Espejo: missing data-key (the project's public key)");this.config={...t,ingestUrl:t.ingestUrl||Mo,mode:t.mode||"ring"},this.pristineFetch=typeof globalThis.fetch=="function"?globalThis.fetch.bind(globalThis):void 0}get recording(){return this.recorder!==null}start(){if(this.recorder)return;let t=new V(this.config.budgets);this.recorder=t,this.autoKilled=this.config.autoReport==="off",this.config.capture==="dom"&&(this.routeSnapshot=qt({ingestUrl:this.config.ingestUrl,key:this.config.key,getSnapshot:()=>this.snapshotFn,fetchImpl:this.pristineFetch})),this.uninstall=[Ht(t,{ignoreOrigins:[this.config.ingestUrl],onEntry:n=>this.onNetworkEntry(n)}),Ft(t,{onEntry:(n,o)=>this.onConsoleEntry(n,o)}),Ut(t,{onEntry:(n,o)=>this.pushTriggerSignal({kind:n,tMs:o})}),$t(t,n=>{this.routeSnapshot?.onRoute(),this.pushTriggerSignal({kind:"nav",tMs:t.elapsed(),url:n})})],this.config.capture==="dom"&&this.enableDom(t),this.config.button!=="off"&&(this.widget=nn({report:(n,o)=>this.report(n,ln,o),text:this.config.buttonText,theme:this.config.theme,position:this.config.position,icon:this.config.buttonIcon,video:{supported:()=>K(),start:n=>this.startVideo(n),setMicrophone:n=>this.setMicrophone(n),stop:async()=>{await this.stopVideo()},discard:()=>this.discardVideo(),setMarkup:(n,o)=>this.setMarkup(n,o),limitSeconds:240}})),this.loadAutoReport(),this.config.feedback!=="off"&&this.loadFeedback()}pushTriggerSignal(t){try{this.triggerSink?this.triggerSink(t):this.triggerBuf.length<300&&this.triggerBuf.push(t)}catch{}}async loadTriggers(){if(!this.recorder||this.triggersStop)return;let t=await ye(this.config.ingestUrl,"espejo.triggers.js",Yt);if(!(!t||!this.recorder||this.triggersStop))try{let n=t({ingestUrl:this.config.ingestUrl,key:this.config.key,fetchImpl:this.pristineFetch,now:()=>this.recorder?.elapsed()??0,subscribe:o=>{this.triggerSink=o;for(let r of this.triggerBuf.splice(0))o(r)},theme:this.config.theme});n&&(this.triggersStop=n.stop)}catch{}}async loadFeedback(){let t=await ge(this.config.ingestUrl,this.config.key,this.pristineFetch);t?.enabled&&(!this.recorder||this.feedback||Se(this.config.key,t.cadence_days)&&(_e(this.config.key),this.feedback=Ee({config:t,vote:n=>ve({ingestUrl:this.config.ingestUrl,key:this.config.key,kind:t.kind,value:n,pageHost:typeof location<"u"?location.host:void 0,userRef:this.config.userRef},this.pristineFetch),text:this.config.feedbackText,theme:this.config.theme})))}async loadAutoReport(){let{config:t,videoSurface:n,hasTriggers:o}=await me(this.config.ingestUrl,this.config.key,this.pristineFetch);n&&(this.config.videoSurface=n),o&&this.loadTriggers(),t&&(this.autoConfig=t,this.autoGuard=new Lt(t))}setAutoReport(t){this.autoKilled=!t}identify(t){this.config.userRef=t||void 0}canOpenReport(){return!!this.widget&&!this.video}openReport(){let t=this.canOpenReport();return t&&this.widget.open(),t}get lastReportId(){return this.lastReport}get autoReportActive(){return!!this.autoConfig&&!this.autoKilled}autoEnabled(t){return this.autoKilled||!this.autoConfig||!this.recorder?!1:this.autoConfig.triggers.includes(t)}onConsoleEntry(t,n){if(n==="console"&&t.level!=="error")return;this.pushTriggerSignal({kind:"console_error",tMs:this.recorder?.elapsed()??0});let o=n==="window_error"?"auto:uncaught":n==="unhandled_rejection"?"auto:unhandled_rejection":"auto:console_error";this.maybeAutoReport(o,Ue(o,t.text,t.stack))}onNetworkEntry(t){let n=Mt(t.status,!!t.error);n&&(this.pushTriggerSignal({kind:"http_error",tMs:this.recorder?.elapsed()??0}),this.maybeAutoReport(n,Ue(n,`${t.method} ${t.url}`,String(t.status??t.error))))}maybeAutoReport(t,n){try{if(!this.autoEnabled(t)||this.autoInFlight||!this.autoGuard?.check(n).allowed)return;this.autoInFlight=!0,this.report(void 0,{source:"auto",trigger:t}).catch(()=>{}).finally(()=>{this.autoInFlight=!1})}catch{this.autoInFlight=!1}}async enableDom(t){let n=this.config.rrwebRecord??await Gt();if(!n||this.recorder!==t)return;this.dom=Wt(t,n);let o=this.config.rrwebSnapshot??await Vt();this.recorder===t&&(this.snapshotFn=o,o&&this.routeSnapshot?.onRoute())}stop(){for(let t of this.uninstall.splice(0))try{t()}catch{}this.dom?.stop(),this.dom=null,this.routeSnapshot?.stop(),this.routeSnapshot=null,this.snapshotFn=null,this.widget?.destroy(),this.widget=null,this.feedback?.destroy(),this.feedback=null;try{this.triggersStop?.()}catch{}this.triggersStop=null,this.triggerSink=null,this.triggerBuf=[],this.teardownMarkup(),this.recorder=null}async startVideo(t={}){if(!K())throw new Error("This browser can't record the screen.");this.video||(this.video=await Kt({...t,surface:t.surface??this.config.videoSurface}),this.videoContentType=this.video.contentType)}async setMicrophone(t){return await this.video?.setMicrophone(t)??{on:!1,denied:!1}}get microphoneOn(){return this.video?.microphoneOn??!1}async stopVideo(){return this.video?(this.videoHasAudio=this.video.hasAudio,this.videoBlob=await this.video.stop(),this.videoMs=this.video.durationMs,this.video=null,this.videoBlob):null}get recordingVideo(){return this.video!==null}async setMarkup(t,n=()=>{}){if(!t)return this.teardownMarkup(),!1;if(this.annotator)return!0;if(typeof document>"u")return!1;let o=await an(this.config.ingestUrl);if(!o)return!1;let r=document.createElement("div");r.setAttribute("data-espejo-markup","");let a=r.attachShadow({mode:"closed"});return document.body.appendChild(r),this.markupHost=r,this.annotator=o({root:a,onExit:()=>{this.teardownMarkup(),n()}}),this.annotator?!0:(this.teardownMarkup(),!1)}teardownMarkup(){this.annotator?.destroy(),this.annotator=null,this.markupHost?.remove(),this.markupHost=null}discardVideo(){this.videoBlob=null,this.videoHasAudio=!1,this.videoMs=0}snapshot(){return this.recorder?.snapshot()??null}async report(t,n=ln,o){let r=this.recorder;if(!r)return null;let a=n.source==="auto";this.video&&!a&&await this.stopVideo();let i=r.snapshot(),s=this.dom?.events(),l=!a&&this.videoBlob?{blob:this.videoBlob,contentType:this.videoContentType}:void 0,p=await Jt({ingestUrl:this.config.ingestUrl,key:this.config.key,manifest:this.manifest(r,t,{dom:!!s?.length,video:!!l,audio:!!l&&this.videoHasAudio},n),events:i,dom:s?.length?s:void 0,video:l,onProgress:a?void 0:o},this.pristineFetch);return r.clear(),this.dom?.buffer.clear(),a||(this.videoBlob=null,this.videoHasAudio=!1,this.videoMs=0,this.lastReport=p.session_id),p.url}manifest(t,n,o,r){return{bundle_version:_t,source:"web-sdk",mode:o.video?"video":o.dom?"dom":"events",trigger:r.source==="auto"?r.trigger:this.config.mode==="always"?"always":"manual",report_source:r.source,description:n??null,started_at:t.startedAtIso,duration_ms:t.elapsed(),page:{host:typeof location<"u"?location.host:null,url:typeof location<"u"?T(location.href):null},app:{release:this.config.release??null,env:this.config.env??null},user_ref:this.config.userRef??null,sdk:{name:dn,version:cn},dropped:{...t.dropped,dom_segments:this.dom?.buffer.droppedCount??0},has_dom:o.dom,has_video:o.video,...o.video?{video_ms:this.videoMs}:{},has_audio:o.audio}}};function Io(e={}){if(typeof document>"u")return null;let t=document.currentScript,n=t?.dataset.key;if(!n)return null;let o=new Te({...e,key:n,ingestUrl:t?.dataset.ingest,mode:t?.dataset.mode==="always"?"always":"ring",capture:t?.dataset.capture==="dom"?"dom":e.capture??"events",button:t?.dataset.button==="off"?"off":e.button??"on",autoReport:t?.dataset.autoReport==="off"?"off":e.autoReport??"on",feedback:t?.dataset.feedback==="off"?"off":e.feedback??"on",feedbackText:Do(t?.dataset.feedbackText)??e.feedbackText,theme:Bo(t?.dataset.theme)??e.theme??"auto",position:Oo(t?.dataset.position)??e.position,buttonIcon:t?.dataset.buttonIcon??e.buttonIcon,videoSurface:t?.dataset.videoSurface,release:t?.dataset.release,env:t?.dataset.env,userRef:t?.dataset.userRef??e.userRef});return o.start(),globalThis.espejo=o,o}function Bo(e){return e==="light"||e==="dark"||e==="auto"?e:void 0}function Oo(e){return e==="bottom-right"||e==="bottom-left"||e==="top-right"||e==="top-left"?e:void 0}function Do(e){if(e)try{let t=JSON.parse(e);return t&&typeof t=="object"?t:void 0}catch{return}}0&&(module.exports={BLOCK_ATTRIBUTE,BLOCK_SELECTOR,DEFAULT_BUDGETS,Espejo,FEEDBACK_DEFAULT_TEXT,MASK_SELECTOR,MAX_VIDEO_SECONDS,RingBuffer,SDK_NAME,SDK_VERSION,SegmentRing,SessionRecorder,WIDGET_DEFAULT_TEXT,autoStart,canShowFeedback,fetchAutoReportConfig,fetchFeedbackConfig,installFeedbackWidget,normalizeAutoReportConfig,normalizeFeedbackConfig,sealFeedbackShown,sendVote,videoSupported});
package/dist/index.d.cts CHANGED
@@ -213,7 +213,7 @@ interface VoteInput {
213
213
  declare function sendVote(input: VoteInput, fetchImpl?: typeof fetch): Promise<void>;
214
214
 
215
215
  declare const SDK_NAME = "@espejo/browser";
216
- declare const SDK_VERSION = "0.1.0";
216
+ declare const SDK_VERSION = "0.2.0";
217
217
  interface EspejoConfig {
218
218
  key: string;
219
219
  ingestUrl?: string;
package/dist/index.d.ts CHANGED
@@ -213,7 +213,7 @@ interface VoteInput {
213
213
  declare function sendVote(input: VoteInput, fetchImpl?: typeof fetch): Promise<void>;
214
214
 
215
215
  declare const SDK_NAME = "@espejo/browser";
216
- declare const SDK_VERSION = "0.1.0";
216
+ declare const SDK_VERSION = "0.2.0";
217
217
  interface EspejoConfig {
218
218
  key: string;
219
219
  ingestUrl?: string;
package/dist/index.js CHANGED
@@ -478,4 +478,4 @@ import{E as oo,F as mt,G as le,H as ce,I as ue,a as Te,b as T,c as K,d as je,e a
478
478
  <p class="ef-title" id="ef-title">${n.title}</p>
479
479
  <div class="ef-options" id="ef-options" role="group" aria-label="${n.title}" data-kind="${t.kind}">${l}</div>
480
480
  <p class="ef-thanks" id="ef-thanks" role="status" aria-live="polite" hidden>${n.thanks}</p>
481
- </div>`;let h=i.querySelector(".ef-root"),m=i.getElementById("ef-close"),c=i.getElementById("ef-title"),p=i.getElementById("ef-options"),w=i.getElementById("ef-thanks"),k=Array.from(p.querySelectorAll(".ef-opt")),f=!1,b=null,j=()=>{b!==null&&(e.defaultView?.clearTimeout(b),b=null)},x=()=>{j(),e.removeEventListener("keydown",A,!0),d.remove()},F=g=>{if(!f){f=!0;for(let M of k)M.disabled=!0;o(g).catch(()=>{}),c.hidden=!0,p.hidden=!0,w.hidden=!1,b=e.defaultView?.setTimeout(x,1600)??null}},A=g=>{g.key==="Escape"&&(g.stopPropagation(),x())},C=g=>{let M=g.currentTarget??null;M&&F(Number(M.dataset.value))};for(let g of k)g.addEventListener("click",C);m.addEventListener("click",x);let y=ce(h);return e.addEventListener("keydown",A,!0),e.body.appendChild(d),{destroy(){j();for(let g of k)g.removeEventListener("click",C);m.removeEventListener("click",x),y(),e.removeEventListener("keydown",A,!0),d.remove()},shadowRootForTesting:i}}var Do="espejo:feedback:lastShown:";function $t(e){return`${Do}${e}`}function Oe(e,t,o){try{let n=Wt(o);if(!n)return!0;let s=n.getItem($t(e));if(!s)return!0;let d=Number(s);return Number.isFinite(d)?Date.now()-d>=t*864e5:!0}catch{return!0}}function Pe(e,t){try{Wt(t)?.setItem($t(e),String(Date.now()))}catch{}}function Wt(e){return(e?.defaultView??(typeof window<"u"?window:void 0))?.localStorage??null}var Ho="__espejoInstallAnnotator";function Nt(e,t=document){return me(e,"espejo.draw.js",Ho,t)}var Io="@espejo/browser",Oo="0.1.0",Po="https://app.espejo.dev",Vt={source:"manual"},Fe=class{constructor(t){this.recorder=null;this.uninstall=[];this.dom=null;this.routeSnapshot=null;this.snapshotFn=null;this.widget=null;this.lastReport=null;this.feedback=null;this.annotator=null;this.markupHost=null;this.video=null;this.videoBlob=null;this.videoContentType="video/webm";this.videoHasAudio=!1;this.videoMs=0;this.autoConfig=null;this.autoGuard=null;this.autoKilled=!1;this.autoInFlight=!1;this.triggerSink=null;this.triggerBuf=[];this.triggersStop=null;if(!t?.key)throw new Error("Espejo: missing data-key (the project's public key)");this.config={...t,ingestUrl:t.ingestUrl||Po,mode:t.mode||"ring"},this.pristineFetch=typeof globalThis.fetch=="function"?globalThis.fetch.bind(globalThis):void 0}get recording(){return this.recorder!==null}start(){if(this.recorder)return;let t=new q(this.config.budgets);this.recorder=t,this.autoKilled=this.config.autoReport==="off",this.config.capture==="dom"&&(this.routeSnapshot=jt({ingestUrl:this.config.ingestUrl,key:this.config.key,getSnapshot:()=>this.snapshotFn,fetchImpl:this.pristineFetch})),this.uninstall=[kt(t,{ignoreOrigins:[this.config.ingestUrl],onEntry:o=>this.onNetworkEntry(o)}),wt(t,{onEntry:(o,n)=>this.onConsoleEntry(o,n)}),mt(t,{onEntry:(o,n)=>this.pushTriggerSignal({kind:o,tMs:n})}),St(t,o=>{this.routeSnapshot?.onRoute(),this.pushTriggerSignal({kind:"nav",tMs:t.elapsed(),url:o})})],this.config.capture==="dom"&&this.enableDom(t),this.config.button!=="off"&&(this.widget=Pt({report:(o,n)=>this.report(o,Vt,n),text:this.config.buttonText,theme:this.config.theme,position:this.config.position,icon:this.config.buttonIcon,video:{supported:()=>Y(),start:o=>this.startVideo(o),setMicrophone:o=>this.setMicrophone(o),stop:async()=>{await this.stopVideo()},discard:()=>this.discardVideo(),setMarkup:(o,n)=>this.setMarkup(o,n),limitSeconds:240}})),this.loadAutoReport(),this.config.feedback!=="off"&&this.loadFeedback()}pushTriggerSignal(t){try{this.triggerSink?this.triggerSink(t):this.triggerBuf.length<300&&this.triggerBuf.push(t)}catch{}}async loadTriggers(){if(!this.recorder||this.triggersStop)return;let t=await me(this.config.ingestUrl,"espejo.triggers.js",Bt);if(!(!t||!this.recorder||this.triggersStop))try{let o=t({ingestUrl:this.config.ingestUrl,key:this.config.key,fetchImpl:this.pristineFetch,now:()=>this.recorder?.elapsed()??0,subscribe:n=>{this.triggerSink=n;for(let s of this.triggerBuf.splice(0))n(s)},theme:this.config.theme});o&&(this.triggersStop=o.stop)}catch{}}async loadFeedback(){let t=await Me(this.config.ingestUrl,this.config.key,this.pristineFetch);t?.enabled&&(!this.recorder||this.feedback||Oe(this.config.key,t.cadence_days)&&(Pe(this.config.key),this.feedback=Ie({config:t,vote:o=>De({ingestUrl:this.config.ingestUrl,key:this.config.key,kind:t.kind,value:o,pageHost:typeof location<"u"?location.host:void 0,userRef:this.config.userRef},this.pristineFetch),text:this.config.feedbackText,theme:this.config.theme})))}async loadAutoReport(){let{config:t,videoSurface:o,hasTriggers:n}=await Be(this.config.ingestUrl,this.config.key,this.pristineFetch);o&&(this.config.videoSurface=o),n&&this.loadTriggers(),t&&(this.autoConfig=t,this.autoGuard=new ut(t))}setAutoReport(t){this.autoKilled=!t}identify(t){this.config.userRef=t||void 0}canOpenReport(){return!!this.widget&&!this.video}openReport(){let t=this.canOpenReport();return t&&this.widget.open(),t}get lastReportId(){return this.lastReport}get autoReportActive(){return!!this.autoConfig&&!this.autoKilled}autoEnabled(t){return this.autoKilled||!this.autoConfig||!this.recorder?!1:this.autoConfig.triggers.includes(t)}onConsoleEntry(t,o){if(o==="console"&&t.level!=="error")return;this.pushTriggerSignal({kind:"console_error",tMs:this.recorder?.elapsed()??0});let n=o==="window_error"?"auto:uncaught":o==="unhandled_rejection"?"auto:unhandled_rejection":"auto:console_error";this.maybeAutoReport(n,Ae(n,t.text,t.stack))}onNetworkEntry(t){let o=pt(t.status,!!t.error);o&&(this.pushTriggerSignal({kind:"http_error",tMs:this.recorder?.elapsed()??0}),this.maybeAutoReport(o,Ae(o,`${t.method} ${t.url}`,String(t.status??t.error))))}maybeAutoReport(t,o){try{if(!this.autoEnabled(t)||this.autoInFlight||!this.autoGuard?.check(o).allowed)return;this.autoInFlight=!0,this.report(void 0,{source:"auto",trigger:t}).catch(()=>{}).finally(()=>{this.autoInFlight=!1})}catch{this.autoInFlight=!1}}async enableDom(t){let o=this.config.rrwebRecord??await Rt();if(!o||this.recorder!==t)return;this.dom=Et(t,o);let n=this.config.rrwebSnapshot??await Tt();this.recorder===t&&(this.snapshotFn=n,n&&this.routeSnapshot?.onRoute())}stop(){for(let t of this.uninstall.splice(0))try{t()}catch{}this.dom?.stop(),this.dom=null,this.routeSnapshot?.stop(),this.routeSnapshot=null,this.snapshotFn=null,this.widget?.destroy(),this.widget=null,this.feedback?.destroy(),this.feedback=null;try{this.triggersStop?.()}catch{}this.triggersStop=null,this.triggerSink=null,this.triggerBuf=[],this.teardownMarkup(),this.recorder=null}async startVideo(t={}){if(!Y())throw new Error("This browser can't record the screen.");this.video||(this.video=await At({...t,surface:t.surface??this.config.videoSurface}),this.videoContentType=this.video.contentType)}async setMicrophone(t){return await this.video?.setMicrophone(t)??{on:!1,denied:!1}}get microphoneOn(){return this.video?.microphoneOn??!1}async stopVideo(){return this.video?(this.videoHasAudio=this.video.hasAudio,this.videoBlob=await this.video.stop(),this.videoMs=this.video.durationMs,this.video=null,this.videoBlob):null}get recordingVideo(){return this.video!==null}async setMarkup(t,o=()=>{}){if(!t)return this.teardownMarkup(),!1;if(this.annotator)return!0;if(typeof document>"u")return!1;let n=await Nt(this.config.ingestUrl);if(!n)return!1;let s=document.createElement("div");s.setAttribute("data-espejo-markup","");let d=s.attachShadow({mode:"closed"});return document.body.appendChild(s),this.markupHost=s,this.annotator=n({root:d,onExit:()=>{this.teardownMarkup(),o()}}),this.annotator?!0:(this.teardownMarkup(),!1)}teardownMarkup(){this.annotator?.destroy(),this.annotator=null,this.markupHost?.remove(),this.markupHost=null}discardVideo(){this.videoBlob=null,this.videoHasAudio=!1,this.videoMs=0}snapshot(){return this.recorder?.snapshot()??null}async report(t,o=Vt,n){let s=this.recorder;if(!s)return null;let d=o.source==="auto";this.video&&!d&&await this.stopVideo();let i=s.snapshot(),r=this.dom?.events(),l=!d&&this.videoBlob?{blob:this.videoBlob,contentType:this.videoContentType}:void 0,h=await Mt({ingestUrl:this.config.ingestUrl,key:this.config.key,manifest:this.manifest(s,t,{dom:!!r?.length,video:!!l,audio:!!l&&this.videoHasAudio},o),events:i,dom:r?.length?r:void 0,video:l,onProgress:d?void 0:n},this.pristineFetch);return s.clear(),this.dom?.buffer.clear(),d||(this.videoBlob=null,this.videoHasAudio=!1,this.videoMs=0,this.lastReport=h.session_id),h.url}manifest(t,o,n,s){return{bundle_version:st,source:"web-sdk",mode:n.video?"video":n.dom?"dom":"events",trigger:s.source==="auto"?s.trigger:this.config.mode==="always"?"always":"manual",report_source:s.source,description:o??null,started_at:t.startedAtIso,duration_ms:t.elapsed(),page:{host:typeof location<"u"?location.host:null,url:typeof location<"u"?T(location.href):null},app:{release:this.config.release??null,env:this.config.env??null},user_ref:this.config.userRef??null,sdk:{name:Io,version:Oo},dropped:{...t.dropped,dom_segments:this.dom?.buffer.droppedCount??0},has_dom:n.dom,has_video:n.video,...n.video?{video_ms:this.videoMs}:{},has_audio:n.audio}}};function Kn(e={}){if(typeof document>"u")return null;let t=document.currentScript,o=t?.dataset.key;if(!o)return null;let n=new Fe({...e,key:o,ingestUrl:t?.dataset.ingest,mode:t?.dataset.mode==="always"?"always":"ring",capture:t?.dataset.capture==="dom"?"dom":e.capture??"events",button:t?.dataset.button==="off"?"off":e.button??"on",autoReport:t?.dataset.autoReport==="off"?"off":e.autoReport??"on",feedback:t?.dataset.feedback==="off"?"off":e.feedback??"on",feedbackText:$o(t?.dataset.feedbackText)??e.feedbackText,theme:Fo(t?.dataset.theme)??e.theme??"auto",position:Uo(t?.dataset.position)??e.position,buttonIcon:t?.dataset.buttonIcon??e.buttonIcon,videoSurface:t?.dataset.videoSurface,release:t?.dataset.release,env:t?.dataset.env,userRef:t?.dataset.userRef??e.userRef});return n.start(),globalThis.espejo=n,n}function Fo(e){return e==="light"||e==="dark"||e==="auto"?e:void 0}function Uo(e){return e==="bottom-right"||e==="bottom-left"||e==="top-right"||e==="top-left"?e:void 0}function $o(e){if(e)try{let t=JSON.parse(e);return t&&typeof t=="object"?t:void 0}catch{return}}export{oo as BLOCK_ATTRIBUTE,fe as BLOCK_SELECTOR,vt as DEFAULT_BUDGETS,Fe as Espejo,Ut as FEEDBACK_DEFAULT_TEXT,ge as MASK_SELECTOR,_e as MAX_VIDEO_SECONDS,P as RingBuffer,Io as SDK_NAME,Oo as SDK_VERSION,J as SegmentRing,q as SessionRecorder,Ot as WIDGET_DEFAULT_TEXT,Kn as autoStart,Oe as canShowFeedback,Be as fetchAutoReportConfig,Me as fetchFeedbackConfig,Ie as installFeedbackWidget,Lt as normalizeAutoReportConfig,_t as normalizeFeedbackConfig,Pe as sealFeedbackShown,De as sendVote,Y as videoSupported};
481
+ </div>`;let h=i.querySelector(".ef-root"),m=i.getElementById("ef-close"),c=i.getElementById("ef-title"),p=i.getElementById("ef-options"),w=i.getElementById("ef-thanks"),k=Array.from(p.querySelectorAll(".ef-opt")),f=!1,b=null,j=()=>{b!==null&&(e.defaultView?.clearTimeout(b),b=null)},x=()=>{j(),e.removeEventListener("keydown",A,!0),d.remove()},F=g=>{if(!f){f=!0;for(let M of k)M.disabled=!0;o(g).catch(()=>{}),c.hidden=!0,p.hidden=!0,w.hidden=!1,b=e.defaultView?.setTimeout(x,1600)??null}},A=g=>{g.key==="Escape"&&(g.stopPropagation(),x())},C=g=>{let M=g.currentTarget??null;M&&F(Number(M.dataset.value))};for(let g of k)g.addEventListener("click",C);m.addEventListener("click",x);let y=ce(h);return e.addEventListener("keydown",A,!0),e.body.appendChild(d),{destroy(){j();for(let g of k)g.removeEventListener("click",C);m.removeEventListener("click",x),y(),e.removeEventListener("keydown",A,!0),d.remove()},shadowRootForTesting:i}}var Do="espejo:feedback:lastShown:";function $t(e){return`${Do}${e}`}function Oe(e,t,o){try{let n=Wt(o);if(!n)return!0;let s=n.getItem($t(e));if(!s)return!0;let d=Number(s);return Number.isFinite(d)?Date.now()-d>=t*864e5:!0}catch{return!0}}function Pe(e,t){try{Wt(t)?.setItem($t(e),String(Date.now()))}catch{}}function Wt(e){return(e?.defaultView??(typeof window<"u"?window:void 0))?.localStorage??null}var Ho="__espejoInstallAnnotator";function Nt(e,t=document){return me(e,"espejo.draw.js",Ho,t)}var Io="@espejo/browser",Oo="0.2.0",Po="https://app.espejo.dev",Vt={source:"manual"},Fe=class{constructor(t){this.recorder=null;this.uninstall=[];this.dom=null;this.routeSnapshot=null;this.snapshotFn=null;this.widget=null;this.lastReport=null;this.feedback=null;this.annotator=null;this.markupHost=null;this.video=null;this.videoBlob=null;this.videoContentType="video/webm";this.videoHasAudio=!1;this.videoMs=0;this.autoConfig=null;this.autoGuard=null;this.autoKilled=!1;this.autoInFlight=!1;this.triggerSink=null;this.triggerBuf=[];this.triggersStop=null;if(!t?.key)throw new Error("Espejo: missing data-key (the project's public key)");this.config={...t,ingestUrl:t.ingestUrl||Po,mode:t.mode||"ring"},this.pristineFetch=typeof globalThis.fetch=="function"?globalThis.fetch.bind(globalThis):void 0}get recording(){return this.recorder!==null}start(){if(this.recorder)return;let t=new q(this.config.budgets);this.recorder=t,this.autoKilled=this.config.autoReport==="off",this.config.capture==="dom"&&(this.routeSnapshot=jt({ingestUrl:this.config.ingestUrl,key:this.config.key,getSnapshot:()=>this.snapshotFn,fetchImpl:this.pristineFetch})),this.uninstall=[kt(t,{ignoreOrigins:[this.config.ingestUrl],onEntry:o=>this.onNetworkEntry(o)}),wt(t,{onEntry:(o,n)=>this.onConsoleEntry(o,n)}),mt(t,{onEntry:(o,n)=>this.pushTriggerSignal({kind:o,tMs:n})}),St(t,o=>{this.routeSnapshot?.onRoute(),this.pushTriggerSignal({kind:"nav",tMs:t.elapsed(),url:o})})],this.config.capture==="dom"&&this.enableDom(t),this.config.button!=="off"&&(this.widget=Pt({report:(o,n)=>this.report(o,Vt,n),text:this.config.buttonText,theme:this.config.theme,position:this.config.position,icon:this.config.buttonIcon,video:{supported:()=>Y(),start:o=>this.startVideo(o),setMicrophone:o=>this.setMicrophone(o),stop:async()=>{await this.stopVideo()},discard:()=>this.discardVideo(),setMarkup:(o,n)=>this.setMarkup(o,n),limitSeconds:240}})),this.loadAutoReport(),this.config.feedback!=="off"&&this.loadFeedback()}pushTriggerSignal(t){try{this.triggerSink?this.triggerSink(t):this.triggerBuf.length<300&&this.triggerBuf.push(t)}catch{}}async loadTriggers(){if(!this.recorder||this.triggersStop)return;let t=await me(this.config.ingestUrl,"espejo.triggers.js",Bt);if(!(!t||!this.recorder||this.triggersStop))try{let o=t({ingestUrl:this.config.ingestUrl,key:this.config.key,fetchImpl:this.pristineFetch,now:()=>this.recorder?.elapsed()??0,subscribe:n=>{this.triggerSink=n;for(let s of this.triggerBuf.splice(0))n(s)},theme:this.config.theme});o&&(this.triggersStop=o.stop)}catch{}}async loadFeedback(){let t=await Me(this.config.ingestUrl,this.config.key,this.pristineFetch);t?.enabled&&(!this.recorder||this.feedback||Oe(this.config.key,t.cadence_days)&&(Pe(this.config.key),this.feedback=Ie({config:t,vote:o=>De({ingestUrl:this.config.ingestUrl,key:this.config.key,kind:t.kind,value:o,pageHost:typeof location<"u"?location.host:void 0,userRef:this.config.userRef},this.pristineFetch),text:this.config.feedbackText,theme:this.config.theme})))}async loadAutoReport(){let{config:t,videoSurface:o,hasTriggers:n}=await Be(this.config.ingestUrl,this.config.key,this.pristineFetch);o&&(this.config.videoSurface=o),n&&this.loadTriggers(),t&&(this.autoConfig=t,this.autoGuard=new ut(t))}setAutoReport(t){this.autoKilled=!t}identify(t){this.config.userRef=t||void 0}canOpenReport(){return!!this.widget&&!this.video}openReport(){let t=this.canOpenReport();return t&&this.widget.open(),t}get lastReportId(){return this.lastReport}get autoReportActive(){return!!this.autoConfig&&!this.autoKilled}autoEnabled(t){return this.autoKilled||!this.autoConfig||!this.recorder?!1:this.autoConfig.triggers.includes(t)}onConsoleEntry(t,o){if(o==="console"&&t.level!=="error")return;this.pushTriggerSignal({kind:"console_error",tMs:this.recorder?.elapsed()??0});let n=o==="window_error"?"auto:uncaught":o==="unhandled_rejection"?"auto:unhandled_rejection":"auto:console_error";this.maybeAutoReport(n,Ae(n,t.text,t.stack))}onNetworkEntry(t){let o=pt(t.status,!!t.error);o&&(this.pushTriggerSignal({kind:"http_error",tMs:this.recorder?.elapsed()??0}),this.maybeAutoReport(o,Ae(o,`${t.method} ${t.url}`,String(t.status??t.error))))}maybeAutoReport(t,o){try{if(!this.autoEnabled(t)||this.autoInFlight||!this.autoGuard?.check(o).allowed)return;this.autoInFlight=!0,this.report(void 0,{source:"auto",trigger:t}).catch(()=>{}).finally(()=>{this.autoInFlight=!1})}catch{this.autoInFlight=!1}}async enableDom(t){let o=this.config.rrwebRecord??await Rt();if(!o||this.recorder!==t)return;this.dom=Et(t,o);let n=this.config.rrwebSnapshot??await Tt();this.recorder===t&&(this.snapshotFn=n,n&&this.routeSnapshot?.onRoute())}stop(){for(let t of this.uninstall.splice(0))try{t()}catch{}this.dom?.stop(),this.dom=null,this.routeSnapshot?.stop(),this.routeSnapshot=null,this.snapshotFn=null,this.widget?.destroy(),this.widget=null,this.feedback?.destroy(),this.feedback=null;try{this.triggersStop?.()}catch{}this.triggersStop=null,this.triggerSink=null,this.triggerBuf=[],this.teardownMarkup(),this.recorder=null}async startVideo(t={}){if(!Y())throw new Error("This browser can't record the screen.");this.video||(this.video=await At({...t,surface:t.surface??this.config.videoSurface}),this.videoContentType=this.video.contentType)}async setMicrophone(t){return await this.video?.setMicrophone(t)??{on:!1,denied:!1}}get microphoneOn(){return this.video?.microphoneOn??!1}async stopVideo(){return this.video?(this.videoHasAudio=this.video.hasAudio,this.videoBlob=await this.video.stop(),this.videoMs=this.video.durationMs,this.video=null,this.videoBlob):null}get recordingVideo(){return this.video!==null}async setMarkup(t,o=()=>{}){if(!t)return this.teardownMarkup(),!1;if(this.annotator)return!0;if(typeof document>"u")return!1;let n=await Nt(this.config.ingestUrl);if(!n)return!1;let s=document.createElement("div");s.setAttribute("data-espejo-markup","");let d=s.attachShadow({mode:"closed"});return document.body.appendChild(s),this.markupHost=s,this.annotator=n({root:d,onExit:()=>{this.teardownMarkup(),o()}}),this.annotator?!0:(this.teardownMarkup(),!1)}teardownMarkup(){this.annotator?.destroy(),this.annotator=null,this.markupHost?.remove(),this.markupHost=null}discardVideo(){this.videoBlob=null,this.videoHasAudio=!1,this.videoMs=0}snapshot(){return this.recorder?.snapshot()??null}async report(t,o=Vt,n){let s=this.recorder;if(!s)return null;let d=o.source==="auto";this.video&&!d&&await this.stopVideo();let i=s.snapshot(),r=this.dom?.events(),l=!d&&this.videoBlob?{blob:this.videoBlob,contentType:this.videoContentType}:void 0,h=await Mt({ingestUrl:this.config.ingestUrl,key:this.config.key,manifest:this.manifest(s,t,{dom:!!r?.length,video:!!l,audio:!!l&&this.videoHasAudio},o),events:i,dom:r?.length?r:void 0,video:l,onProgress:d?void 0:n},this.pristineFetch);return s.clear(),this.dom?.buffer.clear(),d||(this.videoBlob=null,this.videoHasAudio=!1,this.videoMs=0,this.lastReport=h.session_id),h.url}manifest(t,o,n,s){return{bundle_version:st,source:"web-sdk",mode:n.video?"video":n.dom?"dom":"events",trigger:s.source==="auto"?s.trigger:this.config.mode==="always"?"always":"manual",report_source:s.source,description:o??null,started_at:t.startedAtIso,duration_ms:t.elapsed(),page:{host:typeof location<"u"?location.host:null,url:typeof location<"u"?T(location.href):null},app:{release:this.config.release??null,env:this.config.env??null},user_ref:this.config.userRef??null,sdk:{name:Io,version:Oo},dropped:{...t.dropped,dom_segments:this.dom?.buffer.droppedCount??0},has_dom:n.dom,has_video:n.video,...n.video?{video_ms:this.videoMs}:{},has_audio:n.audio}}};function Kn(e={}){if(typeof document>"u")return null;let t=document.currentScript,o=t?.dataset.key;if(!o)return null;let n=new Fe({...e,key:o,ingestUrl:t?.dataset.ingest,mode:t?.dataset.mode==="always"?"always":"ring",capture:t?.dataset.capture==="dom"?"dom":e.capture??"events",button:t?.dataset.button==="off"?"off":e.button??"on",autoReport:t?.dataset.autoReport==="off"?"off":e.autoReport??"on",feedback:t?.dataset.feedback==="off"?"off":e.feedback??"on",feedbackText:$o(t?.dataset.feedbackText)??e.feedbackText,theme:Fo(t?.dataset.theme)??e.theme??"auto",position:Uo(t?.dataset.position)??e.position,buttonIcon:t?.dataset.buttonIcon??e.buttonIcon,videoSurface:t?.dataset.videoSurface,release:t?.dataset.release,env:t?.dataset.env,userRef:t?.dataset.userRef??e.userRef});return n.start(),globalThis.espejo=n,n}function Fo(e){return e==="light"||e==="dark"||e==="auto"?e:void 0}function Uo(e){return e==="bottom-right"||e==="bottom-left"||e==="top-right"||e==="top-left"?e:void 0}function $o(e){if(e)try{let t=JSON.parse(e);return t&&typeof t=="object"?t:void 0}catch{return}}export{oo as BLOCK_ATTRIBUTE,fe as BLOCK_SELECTOR,vt as DEFAULT_BUDGETS,Fe as Espejo,Ut as FEEDBACK_DEFAULT_TEXT,ge as MASK_SELECTOR,_e as MAX_VIDEO_SECONDS,P as RingBuffer,Io as SDK_NAME,Oo as SDK_VERSION,J as SegmentRing,q as SessionRecorder,Ot as WIDGET_DEFAULT_TEXT,Kn as autoStart,Oe as canShowFeedback,Be as fetchAutoReportConfig,Me as fetchFeedbackConfig,Ie as installFeedbackWidget,Lt as normalizeAutoReportConfig,_t as normalizeFeedbackConfig,Pe as sealFeedbackShown,De as sendVote,Y as videoSupported};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@espejo/browser",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Espejo browser SDK: session capture, bug reports, the support agent layer and the support chat widget.",
5
5
  "keywords": [
6
6
  "espejo",
@@ -46,7 +46,7 @@
46
46
  "@espejo/core": "0.0.0"
47
47
  },
48
48
  "scripts": {
49
- "build": "tsup && node scripts/assert-bundle-size.mjs",
49
+ "build": "tsup && node scripts/assert-bundle-size.mjs && node scripts/assert-third-party-notices.mjs",
50
50
  "typecheck": "tsc -p tsconfig.json --noEmit"
51
51
  }
52
52
  }