iris-recorder 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,51 +1,57 @@
1
- # iris-recorder
2
-
3
- Browser SDK for **Iris** — self-hosted session replay & frontend monitoring, built by
4
- The Watering Can Flower Market.
5
-
6
- One `record()` call captures session replay (rrweb), errors, network + console
7
- breadcrumbs, WebSocket/SSE frames, Web Vitals, and your own `iris.track()` events —
8
- and ships them, gzipped, to an Iris server **you** run. No third party ever sees a
9
- session.
10
-
11
- > **Heads-up:** this package is only useful against a self-hosted
12
- > [Iris backend](https://github.com/nicolastwc/TWC_Iris). It's on npm so our own
13
- > apps can install it easily — without an Iris server it records nothing, nowhere.
14
-
15
- ## Install
16
-
17
- ```bash
18
- npm i iris-recorder
19
- ```
20
-
21
- ## Quickstart
22
-
23
- ```ts
24
- import { record } from 'iris-recorder';
25
-
26
- record({
27
- endpoint: 'https://your-iris-host', // your Iris server origin
28
- projectKey: 'pk_live_…', // from the Iris dashboard → Settings
29
- release: import.meta.env.VITE_GIT_SHA // optional — matches uploaded source maps
30
- });
31
- ```
32
-
33
- Or drop the IIFE build in a `<script>` tag and call `Iris.record({...})`.
34
-
35
- ## Privacy defaults
36
-
37
- - All inputs are masked; add `.twc-mask` to hide text, `.twc-block` to redact regions.
38
- - Network capture is on by default (built for first-party, employees-only apps), but
39
- everything is masked **in the browser** before send: credential headers stripped,
40
- secret-looking body/query keys masked, bodies size-capped, binary as sizes only.
41
- - Tune with `network: { captureBodies, maskExtraKeys, maxBodyChars, … }`, or go
42
- metadata-only with `network: { captureBodies: false }`.
43
- - Telemetry never breaks the host app — every collector swallows its own errors.
44
-
45
- Full options, replay-viewer docs, and the backend itself:
46
- **[github.com/nicolastwc/TWC_Iris](https://github.com/nicolastwc/TWC_Iris)**.
47
-
48
- ## License
49
-
50
- UNLICENSED — published for convenience, all rights reserved by
51
- The Watering Can Flower Market.
1
+ # iris-recorder
2
+
3
+ Browser SDK for **Iris** — self-hosted session replay & frontend monitoring, built by
4
+ The Watering Can Flower Market.
5
+
6
+ One `record()` call captures session replay (rrweb), errors, network + console
7
+ breadcrumbs, WebSocket/SSE frames, Web Vitals, and your own `iris.track()` events —
8
+ and ships them, gzipped, to an Iris server **you** run. No third party ever sees a
9
+ session.
10
+
11
+ > **Heads-up:** this package is only useful against a self-hosted
12
+ > [Iris backend](https://github.com/nicolastwc/TWC_Iris). It's on npm so our own
13
+ > apps can install it easily — without an Iris server it records nothing, nowhere.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm i iris-recorder
19
+ ```
20
+
21
+ ## Quickstart
22
+
23
+ ```ts
24
+ import { record } from 'iris-recorder';
25
+
26
+ record({
27
+ endpoint: 'https://your-iris-host', // your Iris server origin
28
+ projectKey: 'pk_live_…', // from the Iris dashboard → Settings
29
+ release: import.meta.env.VITE_GIT_SHA // optional — matches uploaded source maps
30
+ });
31
+ ```
32
+
33
+ Or drop the IIFE build in a `<script>` tag and call `Iris.record({...})`.
34
+
35
+ A session lasts as long as the tab and lives in `sessionStorage`, which is per-origin.
36
+ If your app sends a visitor to another of its own hosts (say, from a sign-in page on
37
+ `example.com` to `shop.example.com`), pass `handle.sessionId` along and hand it to
38
+ `record({ sessionId })` on the other side to keep one session. `currentSessionId()`
39
+ tells you whether this tab is already recording one.
40
+
41
+ ## Privacy defaults
42
+
43
+ - All inputs are masked; add `.twc-mask` to hide text, `.twc-block` to redact regions.
44
+ - Network capture is on by default (built for first-party, employees-only apps), but
45
+ everything is masked **in the browser** before send: credential headers stripped,
46
+ secret-looking body/query keys masked, bodies size-capped, binary as sizes only.
47
+ - Tune with `network: { captureBodies, maskExtraKeys, maxBodyChars, … }`, or go
48
+ metadata-only with `network: { captureBodies: false }`.
49
+ - Telemetry never breaks the host app — every collector swallows its own errors.
50
+
51
+ Full options, replay-viewer docs, and the backend itself:
52
+ **[github.com/nicolastwc/TWC_Iris](https://github.com/nicolastwc/TWC_Iris)**.
53
+
54
+ ## License
55
+
56
+ UNLICENSED — published for convenience, all rights reserved by
57
+ The Watering Can Flower Market.
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var F=Object.defineProperty;var ye=Object.getOwnPropertyDescriptor;var me=Object.getOwnPropertyNames;var he=Object.prototype.hasOwnProperty;var ge=(e,t,n)=>t in e?F(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var ke=(e,t)=>{for(var n in t)F(e,n,{get:t[n],enumerable:!0})},be=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of me(t))!he.call(e,i)&&i!==n&&F(e,i,{get:()=>t[i],enumerable:!(o=ye(t,i))||o.enumerable});return e};var ve=e=>be(F({},"__esModule",{value:!0}),e);var U=(e,t,n)=>ge(e,typeof t!="symbol"?t+"":t,n);var Ue={};ke(Ue,{record:()=>Oe});module.exports=ve(Ue);function N(e){let n=G(e,1,{keys:32});return n&&Object.keys(n).length>0?n:void 0}function G(e,t,n){if(typeof e!="object"||e===null||Array.isArray(e))return;let o={};for(let[i,d]of Object.entries(e)){if(n.keys<=0)break;let f=i.slice(0,64);if(f){if(typeof d=="string")o[f]=d.slice(0,300),n.keys-=1;else if(typeof d=="number"||typeof d=="boolean")o[f]=String(d),n.keys-=1;else if(typeof d=="object"&&d!==null&&!Array.isArray(d)&&t<3){n.keys-=1;let g=G(d,t+1,n);g&&Object.keys(g).length>0?o[f]=g:n.keys+=1}}}return o}function $(e){for(let t of["id","userId","email","username","name"]){let n=e[t];if(typeof n=="string"&&n)return n}for(let t of Object.values(e))if(typeof t=="string"&&t)return t}function we(){let e="iris.sid";try{let t=sessionStorage.getItem(e);if(t)return t;let n=crypto.randomUUID();return sessionStorage.setItem(e,n),n}catch(t){return crypto.randomUUID()}}function Q(e,t){let n=N(typeof t=="string"?{id:t}:t);return{sessionId:we(),user:n,userId:n?$(n):void 0,release:e,startedAt:Date.now(),url:location.href,userAgent:navigator.userAgent}}var X=require("fflate");var W=class{constructor(t){U(this,"opts",t);U(this,"queue",[]);U(this,"bytes",0);U(this,"timer");U(this,"flushBytes");U(this,"maxBytes",4e6);var n,o;this.flushBytes=(n=t.flushBytes)!=null?n:64e3,this.timer=setInterval(()=>this.flush(!1),(o=t.flushMs)!=null?o:5e3),addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(!0)}),addEventListener("pagehide",()=>this.flush(!0))}push(t){this.queue.push(t),this.bytes+=Z(t),this.bytes>=this.flushBytes&&this.flush(!1)}flush(t){if(this.queue.length===0)return;let n=this.queue;this.queue=[],this.bytes=0;let o={meta:this.opts.meta,events:n},i=(0,X.gzipSync)((0,X.strToU8)(JSON.stringify(o))),d=`${this.opts.endpoint}/v1/ingest`;if(this.log(`flush via ${t?"beacon":"fetch"}: ${n.length} events, ${i.length}b gz \u2192 ${d}`),t&&"sendBeacon"in navigator){let f=!1;try{f=navigator.sendBeacon(d,new Blob([i],{type:"application/octet-stream"}))}catch(g){f=!1}f||(this.log("beacon refused \u2014 re-queueing"),this.requeue(n));return}fetch(d,{method:"POST",body:i,keepalive:t,headers:{"content-encoding":"gzip","content-type":"application/octet-stream","x-iris-key":this.opts.projectKey}}).then(f=>{this.log(`ingest responded ${f.status}`),f.ok||this.requeue(n)}).catch(f=>{this.log("ingest request failed",f),this.requeue(n)})}identify(t){var o;let n=N(typeof t=="string"?{id:t}:t);n&&(this.opts.meta.user=n,this.opts.meta.userId=$(n),this.log(`identified as ${(o=this.opts.meta.userId)!=null?o:"(unnamed user)"}`))}log(...t){this.opts.debug&&console.debug("[iris]",...t)}requeue(t){let n=t.concat(this.queue),o=0;for(let i of n)o+=Z(i);o>this.maxBytes||(this.queue=n,this.bytes=o)}stop(){this.timer&&clearInterval(this.timer),this.flush(!0)}};function Z(e){return JSON.stringify(e).length}var Ee=["authorization","cookie","set-cookie","proxy-authorization","x-api-key","x-auth-token","x-csrf-token","x-xsrf-token"],Se=/pass(word|wd)?|secret|token|api[-_]?key|auth|credential|session|cvv|card[-_]?(number|num)?|ssn|pin/i;var xe="[redacted]",j="[masked]";function D(e={}){var R,b,L,A;let t=new Set([...Ee,...((R=e.redactHeaders)!=null?R:[]).map(l=>l.toLowerCase())]),n=(b=e.maskKeys)!=null?b:Se,o=new Set(((L=e.maskExtraKeys)!=null?L:[]).map(l=>l.toLowerCase())),i=l=>n.test(l)||o.has(l.toLowerCase()),d=(A=e.maxBodyChars)!=null?A:1e4,f=()=>typeof location!="undefined"?location.href:void 0,g=l=>{try{let h=new URL(l,f()),k=!1;for(let x of[...h.searchParams.keys()])i(x)&&(h.searchParams.set(x,j),k=!0);return k?h.toString():l}catch(h){return l}},w=l=>{let h={};for(let k of Object.keys(l))h[k]=t.has(k.toLowerCase())?xe:l[k];return h},S=l=>{if(Array.isArray(l))return l.map(S);if(l&&typeof l=="object"){let h={};for(let[k,x]of Object.entries(l))h[k]=i(k)?j:S(x);return h}return l},I=(l,h=d)=>l.length>h?`${l.slice(0,h)}\u2026[+${l.length-h} chars]`:l;return{maskUrl:g,maskHeaders:w,maskBody:(l,h=d)=>{if(l==null||l==="")return;let k=String(l),x;try{x=JSON.stringify(S(JSON.parse(k)))}catch(_){if(/^[^={}\s]+=[^&]*(?:&[^=]+=[^&]*)*$/.test(k))try{let a=new URLSearchParams(k);for(let r of[...a.keys()])i(r)&&a.set(r,j);x=a.toString()}catch(a){x=k}else x=k}return I(x,h)},maskObject:l=>S(l),truncate:I,isMaskedKey:i,maxBodyChars:d}}var Ie=500,Re=8e3,Le=120;function ee(e,t={},n={}){var w,S;let o=D(t),i=(w=n.maxEvents)!=null?w:Ie,d=(S=n.maxPropsChars)!=null?S:Re,f=0,g=!1;return(I,E)=>{try{let q=typeof I=="string"?I.trim().slice(0,Le):"";if(!q)return;if(f>=i){g||(g=!0,console.warn(`[iris] track() budget exhausted (${i} events) \u2014 further events are dropped`));return}f++;let R={type:"custom",ts:Date.now(),name:q};if(E!=null&&typeof E=="object"){let b=null,L=1/0;try{b=o.maskObject(E),L=JSON.stringify(b).length}catch(A){b=null}R.props=b!=null&&L<=d?b:{"[iris]":`props dropped (${Number.isFinite(L)?`${L} chars > ${d}`:"not serializable"})`}}e(R)}catch(q){}}}var te=require("rrweb");function re(e,t={}){var o;let n=(0,te.record)({emit(i){e({type:"replay",ts:Date.now(),data:i})},maskAllInputs:(o=t.maskAllInputs)!=null?o:!0,maskTextSelector:t.maskTextSelector,blockSelector:t.blockSelector,sampling:{mousemove:50,scroll:150,input:"last"},checkoutEveryNms:3e4});return()=>n==null?void 0:n()}function ne(e){let t=o=>{var i,d,f,g;e({type:"error",ts:Date.now(),source:"error",name:(d=(i=o.error)==null?void 0:i.name)!=null?d:"Error",message:(f=o.message)!=null?f:String(o.error),stack:(g=o.error)==null?void 0:g.stack})},n=o=>{var d,f;let i=o.reason;e({type:"error",ts:Date.now(),source:"unhandledrejection",name:(d=i==null?void 0:i.name)!=null?d:"UnhandledRejection",message:(f=i==null?void 0:i.message)!=null?f:String(i),stack:i==null?void 0:i.stack})};return addEventListener("error",t),addEventListener("unhandledrejection",n),()=>{removeEventListener("error",t),removeEventListener("unhandledrejection",n)}}var se=512e3;function oe(e,t={}){var _;let n=(_=t.ignoreUrls)!=null?_:[],o=t.captureBodies!==!1,{maskUrl:i,maskHeaders:d,maskBody:f,truncate:g,isMaskedKey:w}=D(t),S=a=>typeof a=="string"&&n.some(r=>typeof r=="string"?a.includes(r):r.test(a)),I=a=>{let r={};if(!a)return r;if(typeof Headers!="undefined"&&a instanceof Headers)a.forEach((s,c)=>r[c]=s);else if(Array.isArray(a))for(let s of a)s&&s.length>=2&&(r[String(s[0])]=String(s[1]));else if(typeof a=="object")for(let[s,c]of Object.entries(a))r[s]=String(c);return r},E=a=>!!a&&/(json|text|xml|javascript|x-www-form-urlencoded|html)/i.test(a),q=a=>!!a&&/event-stream/i.test(a),R=a=>{let r={};if(!a)return r;for(let s of a.trim().split(/[\r\n]+/)){let c=s.indexOf(":");c>0&&(r[s.slice(0,c).trim()]=s.slice(c+1).trim())}return r},b=a=>{let r=[];return a.forEach((s,c)=>{typeof s=="string"?r.push(`${c}=${w(c)?j:s}`):r.push(`${c}=[file ${s.name||"blob"} ${s.size}B]`)}),r.join("&")},L=(a,r)=>{var c;let s=r==null?void 0:r.body;if(typeof s=="string")return{text:s,size:s.length};if(typeof URLSearchParams!="undefined"&&s instanceof URLSearchParams){let u=s.toString();return{text:u,size:u.length}}if(typeof FormData!="undefined"&&s instanceof FormData){let u=b(s);return{text:u,size:u.length,premasked:!0}}if(typeof Blob!="undefined"&&s instanceof Blob)return{size:s.size};if(typeof ArrayBuffer!="undefined"){if(s instanceof ArrayBuffer)return{size:s.byteLength};if(ArrayBuffer.isView(s))return{size:s.byteLength}}if(s==null&&typeof Request!="undefined"&&a instanceof Request){let u=a.method.toUpperCase();if(u!=="GET"&&u!=="HEAD"&&!a.bodyUsed){let y=(c=a.headers.get("content-type"))!=null?c:void 0;try{if(y&&/multipart\/form-data/i.test(y))return{textPromise:a.clone().formData().then(b).catch(()=>{}),premasked:!0};if(E(y))return{textPromise:a.clone().text().catch(()=>{})}}catch(m){}}}return{}},A=async a=>{let r=a.body;if(!r||typeof r.getReader!="function"){let m=await a.text();return{text:m,bytes:m.length,complete:!0}}let s=r.getReader(),c=new TextDecoder,u="",y=0;for(;;){let{done:m,value:p}=await s.read();if(m)return{text:u+c.decode(),bytes:y,complete:!0};if(y+=p.byteLength,u+=c.decode(p,{stream:!0}),y>=se)return s.cancel().catch(()=>{}),{text:u,bytes:y,complete:!1}}},l=window.fetch;window.fetch=async function(...a){var m,p,v,M,O;let r=Date.now(),s=a[0],c=typeof s=="string"?s:s instanceof URL?s.href:s instanceof Request?s.url:String(s),u=((p=(m=a[1])==null?void 0:m.method)!=null?p:s instanceof Request?s.method:"GET").toUpperCase(),y={};if(o&&!S(c))try{y=L(s,a[1])}catch(T){y={}}try{let T=await l.apply(this,a);try{if(!S(c)){let B={type:"network",ts:r,method:u,url:i(c),status:T.status,durationMs:Date.now()-r,initiator:"fetch"};if(!o)e(B);else{let pe=(M=(v=a[1])==null?void 0:v.headers)!=null?M:s instanceof Request?s.headers:void 0;B.reqHeaders=d(I(pe)),B.resHeaders=d(I(T.headers));let P=(O=T.headers.get("content-type"))!=null?O:void 0;P&&(B.contentType=P);let z=Number(T.headers.get("content-length"));Number.isFinite(z)&&(B.resSize=z);let K=null;E(P)&&!q(P)&&!(Number.isFinite(z)&&z>se)&&(K=A(T.clone())),(async()=>{var J,Y;try{let H=(J=y.text)!=null?J:y.textPromise?await y.textPromise:void 0;if(H?(B.reqBody=y.premasked?g(H):f(H),B.reqSize=(Y=y.size)!=null?Y:H.length):y.size!=null&&(B.reqSize=y.size),K){let V=await K;V.text&&(B.resBody=f(V.text)),Number.isFinite(z)||(B.resSize=V.bytes)}}catch(H){}e(B)})()}}}catch(B){}return T}catch(T){try{S(c)||e({type:"network",ts:r,method:u,url:i(c),status:0,durationMs:Date.now()-r,initiator:"fetch"})}catch(B){}throw T}};let h=XMLHttpRequest.prototype.open,k=XMLHttpRequest.prototype.send,x=XMLHttpRequest.prototype.setRequestHeader;return XMLHttpRequest.prototype.open=function(a,r,...s){return this.__iris={method:String(a).toUpperCase(),url:String(r),start:0,reqHeaders:{},reqBody:void 0,reqSize:void 0,premasked:!1},h.apply(this,[a,r,...s])},XMLHttpRequest.prototype.setRequestHeader=function(a,r){let s=this.__iris;return s&&(s.reqHeaders[a]=r),x.apply(this,[a,r])},XMLHttpRequest.prototype.send=function(...a){let r=this.__iris;if(r){r.start=Date.now();let s=a[0];typeof s=="string"?(r.reqBody=s,r.reqSize=s.length):typeof URLSearchParams!="undefined"&&s instanceof URLSearchParams?(r.reqBody=s.toString(),r.reqSize=r.reqBody.length):typeof FormData!="undefined"&&s instanceof FormData?(r.reqBody=b(s),r.reqSize=r.reqBody.length,r.premasked=!0):typeof Blob!="undefined"&&s instanceof Blob?r.reqSize=s.size:(typeof ArrayBuffer!="undefined"&&s instanceof ArrayBuffer||typeof ArrayBuffer!="undefined"&&ArrayBuffer.isView(s))&&(r.reqSize=s.byteLength),this.addEventListener("loadend",()=>{var c;try{if(S(r.url))return;let u={type:"network",ts:r.start,method:r.method,url:i(r.url),status:this.status,durationMs:Date.now()-r.start,initiator:"xhr"};if(o){u.reqHeaders=d(r.reqHeaders),u.resHeaders=d(R(this.getAllResponseHeaders()));let y=(c=this.getResponseHeader("content-type"))!=null?c:void 0;y&&(u.contentType=y),r.reqBody!=null&&(u.reqBody=r.premasked?g(r.reqBody):f(r.reqBody)),r.reqSize!=null&&(u.reqSize=r.reqSize);let m=this.responseType;if(m===""||m==="text")try{let p=this.responseText;p&&(u.resBody=f(p),u.resSize=p.length)}catch(p){}else if(m==="json")try{let p=this.response;if(p!=null){let v=JSON.stringify(p);u.resBody=f(v),u.resSize=v.length}}catch(p){}else if(m==="arraybuffer"){let p=this.response;p&&(u.resSize=p.byteLength)}else if(m==="blob"){let p=this.response;p&&(u.resSize=p.size)}}e(u)}catch(u){}})}return k.apply(this,a)},()=>{window.fetch=l,XMLHttpRequest.prototype.open=h,XMLHttpRequest.prototype.send=k,XMLHttpRequest.prototype.setRequestHeader=x}}var Ae=200,Me=2e3,ie=0;function ae(e,t={},n=!1){var k,x,_,a;let o=D(t),i=(k=t.wsMaxFrames)!=null?k:Ae,d=(x=t.wsMaxFrameChars)!=null?x:Me,f=new Set((_=t.wsFrameTypes)!=null?_:["text","binary"]),g=(a=t.ignoreUrls)!=null?a:[],w=r=>{let s=r.trim();if(!s.startsWith("{")&&!s.startsWith("["))return!1;try{return JSON.parse(s),!0}catch(c){return!1}},S=r=>typeof r=="string"?f.has("text")?!0:f.has("json")?w(r):!1:f.has("binary"),I=r=>typeof r=="string"&&g.some(s=>typeof s=="string"?r.includes(s):s.test(r)),E=r=>{try{e(r)}catch(s){}},q=(...r)=>{n&&console.debug("[iris]",...r)},R=r=>{if(typeof r=="string")return{data:o.maskBody(r,d),size:r.length};if(typeof Blob!="undefined"&&r instanceof Blob)return{binary:!0,size:r.size};if(typeof ArrayBuffer!="undefined"){if(r instanceof ArrayBuffer)return{binary:!0,size:r.byteLength};if(ArrayBuffer.isView(r))return{binary:!0,size:r.byteLength}}return{}},b=window.WebSocket,L=!1,A;if(typeof b=="function"){L=!0;class r extends b{constructor(u,y){super(u,y);try{let m=typeof u=="string"?u:String(u);if(I(m))return;let p=`ws${++ie}`,v={sent:0,recv:0,dropped:0};this.__iris={connId:p,budget:v},E({type:"ws",ts:Date.now(),connId:p,op:"open",transport:"websocket",url:o.maskUrl(m)}),this.addEventListener("message",M=>{if(S(M.data)){if(v.recv>=i){v.dropped++;return}v.recv++,E({type:"ws",ts:Date.now(),connId:p,op:"message",transport:"websocket",...R(M.data)})}}),this.addEventListener("close",M=>{E({type:"ws",ts:Date.now(),connId:p,op:"close",transport:"websocket",code:M.code,reason:M.reason||void 0,dropped:v.dropped||void 0}),q(`ws ${p} closed (${M.code}) \u2014 frames \u2191${v.sent} \u2193${v.recv}, dropped ${v.dropped}`)}),this.addEventListener("error",()=>{E({type:"ws",ts:Date.now(),connId:p,op:"error",transport:"websocket"})})}catch(m){}}}A=b.prototype.send;let s=A;b.prototype.send=function(c){try{let u=this.__iris;u&&S(c)&&(u.budget.sent>=i?u.budget.dropped++:(u.budget.sent++,E({type:"ws",ts:Date.now(),connId:u.connId,op:"send",transport:"websocket",...R(c)})))}catch(u){}return s.call(this,c)},window.WebSocket=r}let l=window.EventSource,h=!1;if(typeof l=="function"){h=!0;class r extends l{constructor(c,u){super(c,u);try{let y=typeof c=="string"?c:String(c);if(I(y))return;let m=`es${++ie}`,p={recv:0,dropped:0},v=(O,T)=>{if(S(O.data)){if(p.recv>=i){p.dropped++;return}p.recv++,E({type:"ws",ts:Date.now(),connId:m,op:"message",transport:"eventsource",...T?{event:T}:{},...R(O.data)})}};this.__iris={record:v,mirrored:new Set},E({type:"ws",ts:Date.now(),connId:m,op:"open",transport:"eventsource",url:o.maskUrl(y)}),super.addEventListener("message",O=>v(O)),super.addEventListener("error",()=>{E({type:"ws",ts:Date.now(),connId:m,op:"error",transport:"eventsource"})});let M=this.close.bind(this);this.close=()=>{try{E({type:"ws",ts:Date.now(),connId:m,op:"close",transport:"eventsource",dropped:p.dropped||void 0}),q(`es ${m} closed \u2014 frames \u2193${p.recv}, dropped ${p.dropped}`)}catch(O){}M()}}catch(y){}}addEventListener(c,u,y){try{let m=this.__iris;m&&c!=="message"&&c!=="error"&&c!=="open"&&!m.mirrored.has(c)&&(m.mirrored.add(c),super.addEventListener(c,(p=>m.record(p,c))))}catch(m){}super.addEventListener(c,u,y)}}window.EventSource=r}return()=>{L&&(window.WebSocket=b,A&&(b.prototype.send=A)),h&&(window.EventSource=l)}}var ce=["log","info","warn","error","debug"],Be=e=>typeof e[0]=="string"&&e[0].startsWith("[iris]");function ue(e,t={}){let n=t.captureIrisLogs===!0,o={};for(let i of ce)o[i]=console[i].bind(console),console[i]=(...d)=>{try{(n||!Be(d))&&e({type:"console",ts:Date.now(),level:i,args:d.map(qe)})}catch(f){}o[i](...d)};return()=>{for(let i of ce)o[i]&&(console[i]=o[i])}}function qe(e){if(typeof e=="string")return e;try{return JSON.stringify(e)}catch(t){return String(e)}}var C=require("web-vitals");function de(e){let t=n=>o=>{e({type:"vital",ts:Date.now(),metric:n,value:o.value,rating:o.rating})};(0,C.onLCP)(t("LCP")),(0,C.onCLS)(t("CLS")),(0,C.onINP)(t("INP")),(0,C.onFCP)(t("FCP")),(0,C.onTTFB)(t("TTFB"))}function fe(e){let t=location.href,n=()=>{try{let d=location.href;if(d===t)return;let f=t;t=d,e({type:"navigation",ts:Date.now(),from:f,to:d})}catch(d){}},o=history.pushState,i=history.replaceState;return history.pushState=function(...d){let f=o.apply(this,d);return n(),f},history.replaceState=function(...d){let f=i.apply(this,d);return n(),f},addEventListener("popstate",n),addEventListener("hashchange",n),()=>{history.pushState=o,history.replaceState=i,removeEventListener("popstate",n),removeEventListener("hashchange",n)}}function le(e,t={}){var A,l,h,k,x;let n=(A=t.rageThreshold)!=null?A:3,o=(l=t.rageWindowMs)!=null?l:1e3,i=(h=t.rageRadiusPx)!=null?h:30,d=(k=t.deadWindowMs)!=null?k:2500,f=(x=t.errorWindowMs)!=null?x:2500,g=0,w=0,S=0,I=[],E=()=>{g=Date.now()},q=new MutationObserver(E);q.observe(document,{subtree:!0,childList:!0,attributes:!0,characterData:!0}),addEventListener("scroll",E,!0);let R=()=>{w=Date.now()};addEventListener("error",R,!0),addEventListener("unhandledrejection",R,!0);let b=(_,a,r,s,c,u)=>{e({type:"click",ts:a,kind:_,selector:_e(r),text:Te(r),x:s,y:c,...u?{count:u}:{}})},L=_=>{try{let a=Date.now(),r=_.clientX,s=_.clientY,c=_.target;for(;I.length&&a-I[0].t>o;)I.shift();let u=I.filter(v=>Math.hypot(v.x-r,v.y-s)<=i).length;if(I.push({x:r,y:s,t:a}),u+1>=n&&(S=a,b("rage",a,c,r,s,u+1),I.length=0),u>0)return;let y=w;if(setTimeout(()=>{w>y&&b("error",a,c,r,s)},f),!Ce(c))return;let m=g,p=location.href;setTimeout(()=>{let v=g>m||location.href!==p,M=w>y;!v&&!M&&S<a&&b("dead",a,c,r,s)},d)}catch(a){}};return addEventListener("click",L,!0),()=>{q.disconnect(),removeEventListener("scroll",E,!0),removeEventListener("error",R,!0),removeEventListener("unhandledrejection",R,!0),removeEventListener("click",L,!0)}}function _e(e){var o;if(!e||!e.tagName)return"unknown";let t=e.tagName.toLowerCase();e.id&&(t+=`#${e.id}`);let n=((o=e.getAttribute("class"))!=null?o:"").trim().split(/\s+/).filter(Boolean)[0];return n&&(t+=`.${n}`),t}function Te(e){var t;if(e)try{if(e.closest(".twc-mask, .twc-block"))return;let n=e.getAttribute("aria-label"),o=((t=n!=null?n:e.textContent)!=null?t:"").replace(/\s+/g," ").trim();return o?o.length>50?`${o.slice(0,50)}\u2026`:o:void 0}catch(n){return}}function Ce(e){if(!e||e.closest("input, textarea, select, label"))return!1;if(e.closest('a, button, [role="button"], [onclick]'))return!0;try{return getComputedStyle(e).cursor==="pointer"}catch(t){return!1}}function Oe(e){var f,g;let t=Q(e.release,(f=e.user)!=null?f:e.userId),n=new W({endpoint:e.endpoint,projectKey:e.projectKey,meta:t,debug:e.debug}),o=n.push.bind(n),i=[],d=e.track===!1?()=>{}:ee(o,typeof e.network=="object"?e.network:{},typeof e.track=="object"?e.track:{});if(e.replay!==!1&&i.push(re(o,{maskAllInputs:(g=e.maskAllInputs)!=null?g:!0,maskTextSelector:e.maskTextSelector,blockSelector:e.blockSelector})),e.errors!==!1&&i.push(ne(o)),e.console!==!1&&i.push(ue(o,typeof e.console=="object"?e.console:{})),e.navigation!==!1&&i.push(fe(o)),e.frustration!==!1&&i.push(le(o)),e.vitals!==!1&&de(o),e.network!==!1){let w={ignoreUrls:[`${e.endpoint}/v1/ingest`],...typeof e.network=="object"?e.network:{}};i.push(oe(o,w)),w.captureWebSockets!==!1&&i.push(ae(o,w,e.debug))}return e.debug&&console.debug("[iris] recording",t.sessionId,"\u2192",e.endpoint),{sessionId:t.sessionId,identify:w=>n.identify(w),track:d,flush:()=>n.flush(!1),stop:()=>{i.forEach(w=>w()),n.stop()}}}0&&(module.exports={record});
1
+ "use strict";var F=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var ke=Object.getOwnPropertyNames;var be=Object.prototype.hasOwnProperty;var ve=(e,t,n)=>t in e?F(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var we=(e,t)=>{for(var n in t)F(e,n,{get:t[n],enumerable:!0})},Ee=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of ke(t))!be.call(e,i)&&i!==n&&F(e,i,{get:()=>t[i],enumerable:!(o=ge(t,i))||o.enumerable});return e};var Se=e=>Ee(F({},"__esModule",{value:!0}),e);var O=(e,t,n)=>ve(e,typeof t!="symbol"?t+"":t,n);var je={};we(je,{currentSessionId:()=>G,record:()=>He});module.exports=Se(je);function N(e){let n=ee(e,1,{keys:32});return n&&Object.keys(n).length>0?n:void 0}function ee(e,t,n){if(typeof e!="object"||e===null||Array.isArray(e))return;let o={};for(let[i,d]of Object.entries(e)){if(n.keys<=0)break;let f=i.slice(0,64);if(f){if(typeof d=="string")o[f]=d.slice(0,300),n.keys-=1;else if(typeof d=="number"||typeof d=="boolean")o[f]=String(d),n.keys-=1;else if(typeof d=="object"&&d!==null&&!Array.isArray(d)&&t<3){n.keys-=1;let h=ee(d,t+1,n);h&&Object.keys(h).length>0?o[f]=h:n.keys+=1}}}return o}function $(e){for(let t of["id","userId","email","username","name"]){let n=e[t];if(typeof n=="string"&&n)return n}for(let t of Object.values(e))if(typeof t=="string"&&t)return t}var J="iris.sid",xe=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function Y(e){return typeof e=="string"&&xe.test(e)}function G(){try{let e=sessionStorage.getItem(J);return Y(e)?e:void 0}catch(e){return}}function Ie(e){try{if(Y(e))return sessionStorage.setItem(J,e),e;let t=G();if(t)return t;let n=crypto.randomUUID();return sessionStorage.setItem(J,n),n}catch(t){return Y(e)?e:crypto.randomUUID()}}function te(e,t,n){let o=N(typeof t=="string"?{id:t}:t);return{sessionId:Ie(n),user:o,userId:o?$(o):void 0,release:e,startedAt:Date.now(),url:location.href,userAgent:navigator.userAgent}}var K=require("fflate");var W=class{constructor(t){O(this,"opts",t);O(this,"queue",[]);O(this,"bytes",0);O(this,"timer");O(this,"flushBytes");O(this,"maxBytes",4e6);var n,o;this.flushBytes=(n=t.flushBytes)!=null?n:64e3,this.timer=setInterval(()=>this.flush(!1),(o=t.flushMs)!=null?o:5e3),addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&this.flush(!0)}),addEventListener("pagehide",()=>this.flush(!0))}push(t){this.queue.push(t),this.bytes+=re(t),this.bytes>=this.flushBytes&&this.flush(!1)}flush(t){if(this.queue.length===0)return;let n=this.queue;this.queue=[],this.bytes=0;let o={meta:this.opts.meta,events:n},i=(0,K.gzipSync)((0,K.strToU8)(JSON.stringify(o))),d=`${this.opts.endpoint}/v1/ingest`;if(this.log(`flush via ${t?"beacon":"fetch"}: ${n.length} events, ${i.length}b gz \u2192 ${d}`),t&&"sendBeacon"in navigator){let f=!1;try{let h=`${d}?k=${encodeURIComponent(this.opts.projectKey)}`;f=navigator.sendBeacon(h,new Blob([i],{type:"text/plain"}))}catch(h){f=!1}f||(this.log("beacon refused \u2014 re-queueing"),this.requeue(n));return}fetch(d,{method:"POST",body:i,keepalive:t,headers:{"content-encoding":"gzip","content-type":"application/octet-stream","x-iris-key":this.opts.projectKey}}).then(f=>{this.log(`ingest responded ${f.status}`),f.ok||this.requeue(n)}).catch(f=>{this.log("ingest request failed",f),this.requeue(n)})}identify(t){var o;let n=N(typeof t=="string"?{id:t}:t);n&&(this.opts.meta.user=n,this.opts.meta.userId=$(n),this.log(`identified as ${(o=this.opts.meta.userId)!=null?o:"(unnamed user)"}`))}log(...t){this.opts.debug&&console.debug("[iris]",...t)}requeue(t){let n=t.concat(this.queue),o=0;for(let i of n)o+=re(i);o>this.maxBytes||(this.queue=n,this.bytes=o)}stop(){this.timer&&clearInterval(this.timer),this.flush(!0)}};function re(e){return JSON.stringify(e).length}var Re=["authorization","cookie","set-cookie","proxy-authorization","x-api-key","x-auth-token","x-csrf-token","x-xsrf-token"],Le=/pass(word|wd)?|secret|token|api[-_]?key|auth|credential|session|cvv|card[-_]?(number|num)?|ssn|pin/i;var Ae="[redacted]",j="[masked]";function D(e={}){var R,b,L,A;let t=new Set([...Re,...((R=e.redactHeaders)!=null?R:[]).map(l=>l.toLowerCase())]),n=(b=e.maskKeys)!=null?b:Le,o=new Set(((L=e.maskExtraKeys)!=null?L:[]).map(l=>l.toLowerCase())),i=l=>n.test(l)||o.has(l.toLowerCase()),d=(A=e.maxBodyChars)!=null?A:1e4,f=()=>typeof location!="undefined"?location.href:void 0,h=l=>{try{let g=new URL(l,f()),k=!1;for(let x of[...g.searchParams.keys()])i(x)&&(g.searchParams.set(x,j),k=!0);return k?g.toString():l}catch(g){return l}},w=l=>{let g={};for(let k of Object.keys(l))g[k]=t.has(k.toLowerCase())?Ae:l[k];return g},S=l=>{if(Array.isArray(l))return l.map(S);if(l&&typeof l=="object"){let g={};for(let[k,x]of Object.entries(l))g[k]=i(k)?j:S(x);return g}return l},I=(l,g=d)=>l.length>g?`${l.slice(0,g)}\u2026[+${l.length-g} chars]`:l;return{maskUrl:h,maskHeaders:w,maskBody:(l,g=d)=>{if(l==null||l==="")return;let k=String(l),x;try{x=JSON.stringify(S(JSON.parse(k)))}catch(_){if(/^[^={}\s]+=[^&]*(?:&[^=]+=[^&]*)*$/.test(k))try{let a=new URLSearchParams(k);for(let r of[...a.keys()])i(r)&&a.set(r,j);x=a.toString()}catch(a){x=k}else x=k}return I(x,g)},maskObject:l=>S(l),truncate:I,isMaskedKey:i,maxBodyChars:d}}var Me=500,Be=8e3,qe=120;function ne(e,t={},n={}){var w,S;let o=D(t),i=(w=n.maxEvents)!=null?w:Me,d=(S=n.maxPropsChars)!=null?S:Be,f=0,h=!1;return(I,E)=>{try{let q=typeof I=="string"?I.trim().slice(0,qe):"";if(!q)return;if(f>=i){h||(h=!0,console.warn(`[iris] track() budget exhausted (${i} events) \u2014 further events are dropped`));return}f++;let R={type:"custom",ts:Date.now(),name:q};if(E!=null&&typeof E=="object"){let b=null,L=1/0;try{b=o.maskObject(E),L=JSON.stringify(b).length}catch(A){b=null}R.props=b!=null&&L<=d?b:{"[iris]":`props dropped (${Number.isFinite(L)?`${L} chars > ${d}`:"not serializable"})`}}e(R)}catch(q){}}}var se=require("rrweb");function oe(e,t={}){var o;let n=(0,se.record)({emit(i){e({type:"replay",ts:Date.now(),data:i})},maskAllInputs:(o=t.maskAllInputs)!=null?o:!0,maskTextSelector:t.maskTextSelector,blockSelector:t.blockSelector,sampling:{mousemove:50,scroll:150,input:"last"},checkoutEveryNms:3e4});return()=>n==null?void 0:n()}function ie(e){let t=o=>{var i,d,f,h;e({type:"error",ts:Date.now(),source:"error",name:(d=(i=o.error)==null?void 0:i.name)!=null?d:"Error",message:(f=o.message)!=null?f:String(o.error),stack:(h=o.error)==null?void 0:h.stack})},n=o=>{var d,f;let i=o.reason;e({type:"error",ts:Date.now(),source:"unhandledrejection",name:(d=i==null?void 0:i.name)!=null?d:"UnhandledRejection",message:(f=i==null?void 0:i.message)!=null?f:String(i),stack:i==null?void 0:i.stack})};return addEventListener("error",t),addEventListener("unhandledrejection",n),()=>{removeEventListener("error",t),removeEventListener("unhandledrejection",n)}}var ae=512e3;function ce(e,t={}){var _;let n=(_=t.ignoreUrls)!=null?_:[],o=t.captureBodies!==!1,{maskUrl:i,maskHeaders:d,maskBody:f,truncate:h,isMaskedKey:w}=D(t),S=a=>typeof a=="string"&&n.some(r=>typeof r=="string"?a.includes(r):r.test(a)),I=a=>{let r={};if(!a)return r;if(typeof Headers!="undefined"&&a instanceof Headers)a.forEach((s,c)=>r[c]=s);else if(Array.isArray(a))for(let s of a)s&&s.length>=2&&(r[String(s[0])]=String(s[1]));else if(typeof a=="object")for(let[s,c]of Object.entries(a))r[s]=String(c);return r},E=a=>!!a&&/(json|text|xml|javascript|x-www-form-urlencoded|html)/i.test(a),q=a=>!!a&&/event-stream/i.test(a),R=a=>{let r={};if(!a)return r;for(let s of a.trim().split(/[\r\n]+/)){let c=s.indexOf(":");c>0&&(r[s.slice(0,c).trim()]=s.slice(c+1).trim())}return r},b=a=>{let r=[];return a.forEach((s,c)=>{typeof s=="string"?r.push(`${c}=${w(c)?j:s}`):r.push(`${c}=[file ${s.name||"blob"} ${s.size}B]`)}),r.join("&")},L=(a,r)=>{var c;let s=r==null?void 0:r.body;if(typeof s=="string")return{text:s,size:s.length};if(typeof URLSearchParams!="undefined"&&s instanceof URLSearchParams){let u=s.toString();return{text:u,size:u.length}}if(typeof FormData!="undefined"&&s instanceof FormData){let u=b(s);return{text:u,size:u.length,premasked:!0}}if(typeof Blob!="undefined"&&s instanceof Blob)return{size:s.size};if(typeof ArrayBuffer!="undefined"){if(s instanceof ArrayBuffer)return{size:s.byteLength};if(ArrayBuffer.isView(s))return{size:s.byteLength}}if(s==null&&typeof Request!="undefined"&&a instanceof Request){let u=a.method.toUpperCase();if(u!=="GET"&&u!=="HEAD"&&!a.bodyUsed){let y=(c=a.headers.get("content-type"))!=null?c:void 0;try{if(y&&/multipart\/form-data/i.test(y))return{textPromise:a.clone().formData().then(b).catch(()=>{}),premasked:!0};if(E(y))return{textPromise:a.clone().text().catch(()=>{})}}catch(m){}}}return{}},A=async a=>{let r=a.body;if(!r||typeof r.getReader!="function"){let m=await a.text();return{text:m,bytes:m.length,complete:!0}}let s=r.getReader(),c=new TextDecoder,u="",y=0;for(;;){let{done:m,value:p}=await s.read();if(m)return{text:u+c.decode(),bytes:y,complete:!0};if(y+=p.byteLength,u+=c.decode(p,{stream:!0}),y>=ae)return s.cancel().catch(()=>{}),{text:u,bytes:y,complete:!1}}},l=window.fetch;window.fetch=async function(...a){var m,p,v,M,U;let r=Date.now(),s=a[0],c=typeof s=="string"?s:s instanceof URL?s.href:s instanceof Request?s.url:String(s),u=((p=(m=a[1])==null?void 0:m.method)!=null?p:s instanceof Request?s.method:"GET").toUpperCase(),y={};if(o&&!S(c))try{y=L(s,a[1])}catch(T){y={}}try{let T=await l.apply(this,a);try{if(!S(c)){let B={type:"network",ts:r,method:u,url:i(c),status:T.status,durationMs:Date.now()-r,initiator:"fetch"};if(!o)e(B);else{let he=(M=(v=a[1])==null?void 0:v.headers)!=null?M:s instanceof Request?s.headers:void 0;B.reqHeaders=d(I(he)),B.resHeaders=d(I(T.headers));let P=(U=T.headers.get("content-type"))!=null?U:void 0;P&&(B.contentType=P);let z=Number(T.headers.get("content-length"));Number.isFinite(z)&&(B.resSize=z);let X=null;E(P)&&!q(P)&&!(Number.isFinite(z)&&z>ae)&&(X=A(T.clone())),(async()=>{var Q,Z;try{let H=(Q=y.text)!=null?Q:y.textPromise?await y.textPromise:void 0;if(H?(B.reqBody=y.premasked?h(H):f(H),B.reqSize=(Z=y.size)!=null?Z:H.length):y.size!=null&&(B.reqSize=y.size),X){let V=await X;V.text&&(B.resBody=f(V.text)),Number.isFinite(z)||(B.resSize=V.bytes)}}catch(H){}e(B)})()}}}catch(B){}return T}catch(T){try{S(c)||e({type:"network",ts:r,method:u,url:i(c),status:0,durationMs:Date.now()-r,initiator:"fetch"})}catch(B){}throw T}};let g=XMLHttpRequest.prototype.open,k=XMLHttpRequest.prototype.send,x=XMLHttpRequest.prototype.setRequestHeader;return XMLHttpRequest.prototype.open=function(a,r,...s){return this.__iris={method:String(a).toUpperCase(),url:String(r),start:0,reqHeaders:{},reqBody:void 0,reqSize:void 0,premasked:!1},g.apply(this,[a,r,...s])},XMLHttpRequest.prototype.setRequestHeader=function(a,r){let s=this.__iris;return s&&(s.reqHeaders[a]=r),x.apply(this,[a,r])},XMLHttpRequest.prototype.send=function(...a){let r=this.__iris;if(r){r.start=Date.now();let s=a[0];typeof s=="string"?(r.reqBody=s,r.reqSize=s.length):typeof URLSearchParams!="undefined"&&s instanceof URLSearchParams?(r.reqBody=s.toString(),r.reqSize=r.reqBody.length):typeof FormData!="undefined"&&s instanceof FormData?(r.reqBody=b(s),r.reqSize=r.reqBody.length,r.premasked=!0):typeof Blob!="undefined"&&s instanceof Blob?r.reqSize=s.size:(typeof ArrayBuffer!="undefined"&&s instanceof ArrayBuffer||typeof ArrayBuffer!="undefined"&&ArrayBuffer.isView(s))&&(r.reqSize=s.byteLength),this.addEventListener("loadend",()=>{var c;try{if(S(r.url))return;let u={type:"network",ts:r.start,method:r.method,url:i(r.url),status:this.status,durationMs:Date.now()-r.start,initiator:"xhr"};if(o){u.reqHeaders=d(r.reqHeaders),u.resHeaders=d(R(this.getAllResponseHeaders()));let y=(c=this.getResponseHeader("content-type"))!=null?c:void 0;y&&(u.contentType=y),r.reqBody!=null&&(u.reqBody=r.premasked?h(r.reqBody):f(r.reqBody)),r.reqSize!=null&&(u.reqSize=r.reqSize);let m=this.responseType;if(m===""||m==="text")try{let p=this.responseText;p&&(u.resBody=f(p),u.resSize=p.length)}catch(p){}else if(m==="json")try{let p=this.response;if(p!=null){let v=JSON.stringify(p);u.resBody=f(v),u.resSize=v.length}}catch(p){}else if(m==="arraybuffer"){let p=this.response;p&&(u.resSize=p.byteLength)}else if(m==="blob"){let p=this.response;p&&(u.resSize=p.size)}}e(u)}catch(u){}})}return k.apply(this,a)},()=>{window.fetch=l,XMLHttpRequest.prototype.open=g,XMLHttpRequest.prototype.send=k,XMLHttpRequest.prototype.setRequestHeader=x}}var _e=200,Te=2e3,ue=0;function de(e,t={},n=!1){var k,x,_,a;let o=D(t),i=(k=t.wsMaxFrames)!=null?k:_e,d=(x=t.wsMaxFrameChars)!=null?x:Te,f=new Set((_=t.wsFrameTypes)!=null?_:["text","binary"]),h=(a=t.ignoreUrls)!=null?a:[],w=r=>{let s=r.trim();if(!s.startsWith("{")&&!s.startsWith("["))return!1;try{return JSON.parse(s),!0}catch(c){return!1}},S=r=>typeof r=="string"?f.has("text")?!0:f.has("json")?w(r):!1:f.has("binary"),I=r=>typeof r=="string"&&h.some(s=>typeof s=="string"?r.includes(s):s.test(r)),E=r=>{try{e(r)}catch(s){}},q=(...r)=>{n&&console.debug("[iris]",...r)},R=r=>{if(typeof r=="string")return{data:o.maskBody(r,d),size:r.length};if(typeof Blob!="undefined"&&r instanceof Blob)return{binary:!0,size:r.size};if(typeof ArrayBuffer!="undefined"){if(r instanceof ArrayBuffer)return{binary:!0,size:r.byteLength};if(ArrayBuffer.isView(r))return{binary:!0,size:r.byteLength}}return{}},b=window.WebSocket,L=!1,A;if(typeof b=="function"){L=!0;class r extends b{constructor(u,y){super(u,y);try{let m=typeof u=="string"?u:String(u);if(I(m))return;let p=`ws${++ue}`,v={sent:0,recv:0,dropped:0};this.__iris={connId:p,budget:v},E({type:"ws",ts:Date.now(),connId:p,op:"open",transport:"websocket",url:o.maskUrl(m)}),this.addEventListener("message",M=>{if(S(M.data)){if(v.recv>=i){v.dropped++;return}v.recv++,E({type:"ws",ts:Date.now(),connId:p,op:"message",transport:"websocket",...R(M.data)})}}),this.addEventListener("close",M=>{E({type:"ws",ts:Date.now(),connId:p,op:"close",transport:"websocket",code:M.code,reason:M.reason||void 0,dropped:v.dropped||void 0}),q(`ws ${p} closed (${M.code}) \u2014 frames \u2191${v.sent} \u2193${v.recv}, dropped ${v.dropped}`)}),this.addEventListener("error",()=>{E({type:"ws",ts:Date.now(),connId:p,op:"error",transport:"websocket"})})}catch(m){}}}A=b.prototype.send;let s=A;b.prototype.send=function(c){try{let u=this.__iris;u&&S(c)&&(u.budget.sent>=i?u.budget.dropped++:(u.budget.sent++,E({type:"ws",ts:Date.now(),connId:u.connId,op:"send",transport:"websocket",...R(c)})))}catch(u){}return s.call(this,c)},window.WebSocket=r}let l=window.EventSource,g=!1;if(typeof l=="function"){g=!0;class r extends l{constructor(c,u){super(c,u);try{let y=typeof c=="string"?c:String(c);if(I(y))return;let m=`es${++ue}`,p={recv:0,dropped:0},v=(U,T)=>{if(S(U.data)){if(p.recv>=i){p.dropped++;return}p.recv++,E({type:"ws",ts:Date.now(),connId:m,op:"message",transport:"eventsource",...T?{event:T}:{},...R(U.data)})}};this.__iris={record:v,mirrored:new Set},E({type:"ws",ts:Date.now(),connId:m,op:"open",transport:"eventsource",url:o.maskUrl(y)}),super.addEventListener("message",U=>v(U)),super.addEventListener("error",()=>{E({type:"ws",ts:Date.now(),connId:m,op:"error",transport:"eventsource"})});let M=this.close.bind(this);this.close=()=>{try{E({type:"ws",ts:Date.now(),connId:m,op:"close",transport:"eventsource",dropped:p.dropped||void 0}),q(`es ${m} closed \u2014 frames \u2193${p.recv}, dropped ${p.dropped}`)}catch(U){}M()}}catch(y){}}addEventListener(c,u,y){try{let m=this.__iris;m&&c!=="message"&&c!=="error"&&c!=="open"&&!m.mirrored.has(c)&&(m.mirrored.add(c),super.addEventListener(c,(p=>m.record(p,c))))}catch(m){}super.addEventListener(c,u,y)}}window.EventSource=r}return()=>{L&&(window.WebSocket=b,A&&(b.prototype.send=A)),g&&(window.EventSource=l)}}var fe=["log","info","warn","error","debug"],Ce=e=>typeof e[0]=="string"&&e[0].startsWith("[iris]");function le(e,t={}){let n=t.captureIrisLogs===!0,o={};for(let i of fe)o[i]=console[i].bind(console),console[i]=(...d)=>{try{(n||!Ce(d))&&e({type:"console",ts:Date.now(),level:i,args:d.map(Ue)})}catch(f){}o[i](...d)};return()=>{for(let i of fe)o[i]&&(console[i]=o[i])}}function Ue(e){if(typeof e=="string")return e;try{return JSON.stringify(e)}catch(t){return String(e)}}var C=require("web-vitals");function pe(e){let t=n=>o=>{e({type:"vital",ts:Date.now(),metric:n,value:o.value,rating:o.rating})};(0,C.onLCP)(t("LCP")),(0,C.onCLS)(t("CLS")),(0,C.onINP)(t("INP")),(0,C.onFCP)(t("FCP")),(0,C.onTTFB)(t("TTFB"))}function ye(e){let t=location.href,n=()=>{try{let d=location.href;if(d===t)return;let f=t;t=d,e({type:"navigation",ts:Date.now(),from:f,to:d})}catch(d){}},o=history.pushState,i=history.replaceState;return history.pushState=function(...d){let f=o.apply(this,d);return n(),f},history.replaceState=function(...d){let f=i.apply(this,d);return n(),f},addEventListener("popstate",n),addEventListener("hashchange",n),()=>{history.pushState=o,history.replaceState=i,removeEventListener("popstate",n),removeEventListener("hashchange",n)}}function me(e,t={}){var A,l,g,k,x;let n=(A=t.rageThreshold)!=null?A:3,o=(l=t.rageWindowMs)!=null?l:1e3,i=(g=t.rageRadiusPx)!=null?g:30,d=(k=t.deadWindowMs)!=null?k:2500,f=(x=t.errorWindowMs)!=null?x:2500,h=0,w=0,S=0,I=[],E=()=>{h=Date.now()},q=new MutationObserver(E);q.observe(document,{subtree:!0,childList:!0,attributes:!0,characterData:!0}),addEventListener("scroll",E,!0);let R=()=>{w=Date.now()};addEventListener("error",R,!0),addEventListener("unhandledrejection",R,!0);let b=(_,a,r,s,c,u)=>{e({type:"click",ts:a,kind:_,selector:Oe(r),text:De(r),x:s,y:c,...u?{count:u}:{}})},L=_=>{try{let a=Date.now(),r=_.clientX,s=_.clientY,c=_.target;for(;I.length&&a-I[0].t>o;)I.shift();let u=I.filter(v=>Math.hypot(v.x-r,v.y-s)<=i).length;if(I.push({x:r,y:s,t:a}),u+1>=n&&(S=a,b("rage",a,c,r,s,u+1),I.length=0),u>0)return;let y=w;if(setTimeout(()=>{w>y&&b("error",a,c,r,s)},f),!ze(c))return;let m=h,p=location.href;setTimeout(()=>{let v=h>m||location.href!==p,M=w>y;!v&&!M&&S<a&&b("dead",a,c,r,s)},d)}catch(a){}};return addEventListener("click",L,!0),()=>{q.disconnect(),removeEventListener("scroll",E,!0),removeEventListener("error",R,!0),removeEventListener("unhandledrejection",R,!0),removeEventListener("click",L,!0)}}function Oe(e){var o;if(!e||!e.tagName)return"unknown";let t=e.tagName.toLowerCase();e.id&&(t+=`#${e.id}`);let n=((o=e.getAttribute("class"))!=null?o:"").trim().split(/\s+/).filter(Boolean)[0];return n&&(t+=`.${n}`),t}function De(e){var t;if(e)try{if(e.closest(".twc-mask, .twc-block"))return;let n=e.getAttribute("aria-label"),o=((t=n!=null?n:e.textContent)!=null?t:"").replace(/\s+/g," ").trim();return o?o.length>50?`${o.slice(0,50)}\u2026`:o:void 0}catch(n){return}}function ze(e){if(!e||e.closest("input, textarea, select, label"))return!1;if(e.closest('a, button, [role="button"], [onclick]'))return!0;try{return getComputedStyle(e).cursor==="pointer"}catch(t){return!1}}function He(e){var f,h;let t=te(e.release,(f=e.user)!=null?f:e.userId,e.sessionId),n=new W({endpoint:e.endpoint,projectKey:e.projectKey,meta:t,debug:e.debug}),o=n.push.bind(n),i=[],d=e.track===!1?()=>{}:ne(o,typeof e.network=="object"?e.network:{},typeof e.track=="object"?e.track:{});if(e.replay!==!1&&i.push(oe(o,{maskAllInputs:(h=e.maskAllInputs)!=null?h:!0,maskTextSelector:e.maskTextSelector,blockSelector:e.blockSelector})),e.errors!==!1&&i.push(ie(o)),e.console!==!1&&i.push(le(o,typeof e.console=="object"?e.console:{})),e.navigation!==!1&&i.push(ye(o)),e.frustration!==!1&&i.push(me(o)),e.vitals!==!1&&pe(o),e.network!==!1){let w={ignoreUrls:[`${e.endpoint}/v1/ingest`],...typeof e.network=="object"?e.network:{}};i.push(ce(o,w)),w.captureWebSockets!==!1&&i.push(de(o,w,e.debug))}return e.debug&&console.debug("[iris] recording",t.sessionId,"\u2192",e.endpoint),{sessionId:t.sessionId,identify:w=>n.identify(w),track:d,flush:()=>n.flush(!1),stop:()=>{i.forEach(w=>w()),n.stop()}}}0&&(module.exports={currentSessionId,record});
2
2
  //# sourceMappingURL=index.cjs.map