@groundcover/browser 0.0.58 → 0.0.60

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
@@ -78,7 +78,17 @@ groundcover.track("custom-event");
78
78
  Capture errors from your web application:
79
79
 
80
80
  ```ts
81
- groundcover.captureException("error");
81
+ groundcover.captureException(new Error("Something went wrong"));
82
+ ```
83
+
84
+ You can also attach metadata to provide additional context:
85
+
86
+ ```ts
87
+ groundcover.captureException(new Error("Payment failed"), {
88
+ userId: "123",
89
+ feature: "checkout",
90
+ cart: { items: 3, total: 99.99 },
91
+ });
82
92
  ```
83
93
 
84
94
  ## Optional Configuration
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  type BaseEvent = {
2
- type: "dom.event" | "exception" | "network" | "log" | "pageload" | "navigation" | "custom" | "performance";
2
+ type: "dom.event" | "exception" | "network" | "log" | "pageload" | "navigation" | "custom" | "performance" | "replay";
3
3
  timestamp?: number;
4
4
  end_timestamp?: number;
5
5
  start_timestamp?: number;
@@ -92,6 +92,7 @@ type ErrorEventAttributes = {
92
92
  error_stacktrace?: Array<Stacktrace>;
93
93
  error_fingerprint: string;
94
94
  error_handled: boolean;
95
+ error_metadata?: Record<string, unknown>;
95
96
  };
96
97
  type LogEventAttributes = {
97
98
  message: string;
@@ -132,6 +133,15 @@ type PerformanceEventAttributes = {
132
133
  performance_metric_id: string;
133
134
  performance_metric_navigation_type: string;
134
135
  };
136
+ type ReplayEventAttributes = {
137
+ replay_data: {
138
+ events: Array<{
139
+ type: number;
140
+ data: unknown;
141
+ timestamp: number;
142
+ }> | string;
143
+ };
144
+ };
135
145
 
136
146
  type Event<T extends BaseEvent["type"], A> = Omit<BaseEvent, "attributes"> & {
137
147
  type: T;
@@ -148,11 +158,12 @@ type EventTypes = {
148
158
  navigation: Event<"navigation", NavigationEventAttributes>;
149
159
  custom: Event<"custom", UserDefinedEventAttributes>;
150
160
  performance: Event<"performance", PerformanceEventAttributes>;
161
+ replay: Event<"replay", ReplayEventAttributes>;
151
162
  };
152
163
  interface SDKOptions {
153
164
  batchSize: number;
154
165
  batchTimeout: number;
155
- enabledEvents: Array<"dom" | "network" | "exceptions" | "logs" | "pageload" | "navigation" | "performance">;
166
+ enabledEvents: Array<"dom" | "network" | "exceptions" | "logs" | "pageload" | "navigation" | "performance" | "replay">;
156
167
  eventSampleRate: number;
157
168
  sessionSampleRate: number;
158
169
  environment: string;
@@ -219,11 +230,13 @@ declare function sendCustomEvent(params: {
219
230
  event: string;
220
231
  attributes: Record<string, unknown>;
221
232
  }): void;
222
- declare function captureException(error: Error): void;
233
+ declare function captureException(error: Error, metadata?: Record<string, unknown>): void;
223
234
  declare function updateConfig(params: Partial<SDKConfig>): void;
224
235
  declare function startNavigation(metadata: Record<string, unknown>): void;
225
236
  declare function endNavigation(metadata: Record<string, unknown>): void;
226
237
  declare function setSessionId(newSessionId?: string): Promise<void>;
238
+ declare function startReplayRecording(): void;
239
+ declare function stopReplayRecording(): void;
227
240
  declare const groundcover: {
228
241
  init: typeof init;
229
242
  identifyUser: typeof identifyUser;
@@ -233,6 +246,8 @@ declare const groundcover: {
233
246
  startNavigation: typeof startNavigation;
234
247
  endNavigation: typeof endNavigation;
235
248
  setSessionId: typeof setSessionId;
249
+ startReplayRecording: typeof startReplayRecording;
250
+ stopReplayRecording: typeof stopReplayRecording;
236
251
  };
237
252
 
238
253
  export { type EventTypes, groundcover as default };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  type BaseEvent = {
2
- type: "dom.event" | "exception" | "network" | "log" | "pageload" | "navigation" | "custom" | "performance";
2
+ type: "dom.event" | "exception" | "network" | "log" | "pageload" | "navigation" | "custom" | "performance" | "replay";
3
3
  timestamp?: number;
4
4
  end_timestamp?: number;
5
5
  start_timestamp?: number;
@@ -92,6 +92,7 @@ type ErrorEventAttributes = {
92
92
  error_stacktrace?: Array<Stacktrace>;
93
93
  error_fingerprint: string;
94
94
  error_handled: boolean;
95
+ error_metadata?: Record<string, unknown>;
95
96
  };
96
97
  type LogEventAttributes = {
97
98
  message: string;
@@ -132,6 +133,15 @@ type PerformanceEventAttributes = {
132
133
  performance_metric_id: string;
133
134
  performance_metric_navigation_type: string;
134
135
  };
136
+ type ReplayEventAttributes = {
137
+ replay_data: {
138
+ events: Array<{
139
+ type: number;
140
+ data: unknown;
141
+ timestamp: number;
142
+ }> | string;
143
+ };
144
+ };
135
145
 
136
146
  type Event<T extends BaseEvent["type"], A> = Omit<BaseEvent, "attributes"> & {
137
147
  type: T;
@@ -148,11 +158,12 @@ type EventTypes = {
148
158
  navigation: Event<"navigation", NavigationEventAttributes>;
149
159
  custom: Event<"custom", UserDefinedEventAttributes>;
150
160
  performance: Event<"performance", PerformanceEventAttributes>;
161
+ replay: Event<"replay", ReplayEventAttributes>;
151
162
  };
152
163
  interface SDKOptions {
153
164
  batchSize: number;
154
165
  batchTimeout: number;
155
- enabledEvents: Array<"dom" | "network" | "exceptions" | "logs" | "pageload" | "navigation" | "performance">;
166
+ enabledEvents: Array<"dom" | "network" | "exceptions" | "logs" | "pageload" | "navigation" | "performance" | "replay">;
156
167
  eventSampleRate: number;
157
168
  sessionSampleRate: number;
158
169
  environment: string;
@@ -219,11 +230,13 @@ declare function sendCustomEvent(params: {
219
230
  event: string;
220
231
  attributes: Record<string, unknown>;
221
232
  }): void;
222
- declare function captureException(error: Error): void;
233
+ declare function captureException(error: Error, metadata?: Record<string, unknown>): void;
223
234
  declare function updateConfig(params: Partial<SDKConfig>): void;
224
235
  declare function startNavigation(metadata: Record<string, unknown>): void;
225
236
  declare function endNavigation(metadata: Record<string, unknown>): void;
226
237
  declare function setSessionId(newSessionId?: string): Promise<void>;
238
+ declare function startReplayRecording(): void;
239
+ declare function stopReplayRecording(): void;
227
240
  declare const groundcover: {
228
241
  init: typeof init;
229
242
  identifyUser: typeof identifyUser;
@@ -233,6 +246,8 @@ declare const groundcover: {
233
246
  startNavigation: typeof startNavigation;
234
247
  endNavigation: typeof endNavigation;
235
248
  setSessionId: typeof setSessionId;
249
+ startReplayRecording: typeof startReplayRecording;
250
+ stopReplayRecording: typeof stopReplayRecording;
236
251
  };
237
252
 
238
253
  export { type EventTypes, groundcover as default };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("fflate"),t=require("error-stack-parser"),n=require("web-vitals");function i(e){return e&&e.__esModule?e:{default:e}}var s=i(t),r=console.log.bind(console),a=class e{constructor(){this.isDebugEnabled=!1,this.prefix=""}static initialize(t){return e.instance||(e.instance=new e),t&&(e.instance.isDebugEnabled=t.debug??!1,e.instance.prefix=t.prefix??""),e.instance}static getInstance(t){return e?.instance||e.initialize(t)}formatMessage(e){return`[${(new Date).toISOString()}] ${this.prefix} ${e}`}log(e,...t){this.isDebugEnabled&&r(this.formatMessage(e),...t)}updateConfig(e){this.isDebugEnabled=e.debug??this.isDebugEnabled,this.prefix=e.prefix??this.prefix}},o=a.getInstance();function l(e){o.log("[error-handler.handleError] called",e,{groundcoverIgnore:!0})}var d={batchSize:10,batchTimeout:1e4,eventSampleRate:1,sessionSampleRate:1,environment:"development",debug:!1,enableCompression:!0,maskFields:[],enableMasking:!1,enabledEvents:[],tracePropagationUrls:[],tracePropagationHeaders:[],tracePropagationTraceIdHeaderName:"",tracePropagationSpanIdHeaderName:"",traceOrigin:{name:"",value:""}},c=class{constructor(e){this.dsn=e?.dsn||"",this.appId=e?.appId||"",this.cluster=e?.cluster||"",this.apiKey=e?.apiKey||"",this.environment=e?.environment||"",this.namespace=e?.namespace||"",this.userIdentifier=e?.userIdentifier||null,this.options={...d,...e?.options||{}}}getEndpoint(){return this.dsn?.startsWith("http")?this.dsn:`https://${this.dsn}`}updateConfig(e){e.options&&(this.options={...this.options,...e.options}),e.userIdentifier&&(this.userIdentifier={...this.userIdentifier,...e.userIdentifier}),e.appId&&(this.appId=e.appId),e.dsn&&(this.dsn=e.dsn),e.apiKey&&(this.apiKey=e.apiKey),e.cluster&&(this.cluster=e.cluster),e.environment&&(this.environment=e.environment),e.namespace&&(this.namespace=e.namespace)}},h=class e{constructor(){this.config=null,this.logger=a.getInstance(),this.sessionId=null}static getInstance(){return e.instance||(e.instance=new e),e.instance}initialize(e){this.config||(this.config=new c(e))}getConfig(){return this.config?this.config:(this.logger.log("[config-manager] configuration not initialized"),null)}getSessionId(){if(this.sessionId)return this.sessionId;const e=globalThis?.sessionStorage?.getItem("gcId");return e||""}setSessionId(e){this.sessionId=e,globalThis?.sessionStorage?.setItem("gcId",e)}updateConfig(e){this.logger.log("[config-manager] updateConfig called"),this.config?(e&&(this.logger.log("[config-manager] updating options"),this.config.updateConfig(e)),e?.userIdentifier&&(this.logger.log("[config-manager] updating user identifier"),this.config.userIdentifier={...this.config.userIdentifier,...e.userIdentifier})):this.logger.log("[config-manager] configuration not initialized")}},g="object"==typeof globalThis?globalThis:"object"==typeof self?self:"object"==typeof window?window:"object"==typeof global?global:{},u=class{constructor(){this.generateTraceId=m(16),this.generateSpanId=m(8),this.generateId=m(16)}},p=Array(32);function m(e){return function(){for(let t=0;t<2*e;t++)p[t]=Math.floor(16*Math.random())+48,p[t]>=58&&(p[t]+=39);return String.fromCharCode.apply(null,p.slice(0,2*e))}}var f=h.getInstance(),v=new u;function y(){const e=f?.getConfig()?.options?.eventSampleRate;return!(void 0!==e&&!Number.isNaN(e))||Math.random()<=e}function E(e,t=""){return Object.entries(e).reduce(((e,[n,i])=>{const s=t?`${t}.${n}`:n;return"object"==typeof i&&null!==i?Object.assign(e,E(i,s)):e[s]=i,e}),{})}function b(e){const t=1e6*Date.now(),n=v.generateId(),i=e.spanId||v.generateSpanId(),s=e.traceId||v.generateTraceId(),r=e.parentSpanId||"",a=E(e.attributes||{}),o=function(){const e=g?.location;return e?{path:e.hash&&!e.hash.match(/^#[a-z0-9-]+$/i)&&e.hash.startsWith("#/")?e.hash:e.pathname,url:e.href,title:g?.document?.title||""}:{path:"",url:"",title:g?.document?.title||""}}(),l={type:e.type,id:n,spanId:i,parentSpanId:r,traceId:s,attributes:{...a,location:o}};return e.span_name&&(l.span_name=e.span_name),"network"===e.type?(l.start_timestamp=e.timestamp||t,l.end_timestamp=e?.end_timestamp):l.timestamp=t,l}var I=class{constructor(){this.logger=a.getInstance(),this.config=h.getInstance()}compress(t){const n=this.config.getConfig();if(!n?.options?.enableCompression)return{data:(new TextEncoder).encode(t),isCompressed:!1};try{const n=e.strToU8(t);return{data:e.gzipSync(n),isCompressed:!0}}catch(e){return{data:(new TextEncoder).encode(t),isCompressed:!1}}}async send(e){const t=this.config.getConfig();if(t)try{t?.options?.debug&&this.logger.log("Sending batch:",e,{groundcoverIgnore:!0});const n=t.apiKey,i=this.buildEndpoint();if(!n)return void this.logger.log("No API key found");const s=JSON.stringify(e),{data:r,isCompressed:a}=this.compress(s);fetch(i,{method:"POST",headers:{"Content-Type":"application/json",apikey:n,"Content-Encoding":a?"gzip":""},body:r}).catch((e=>{this.logger.log("Network error while sending batch:",e,{groundcoverIgnore:!0})}))}catch(e){t.options.debug&&this.logger.log("Failed to send batch:",e,{groundcoverIgnore:!0})}}buildEndpoint(){const e=this.config.getConfig();if(!e)return"";const{dsn:t}=e;return`${t}/json/rum`}},w=["navigation","dom.event"],T=class e{constructor(){this.events=[],this.timeoutId=null,this.config=h.getInstance(),this.logger=a.getInstance(),this.initialized=!1,this.transporter=new I}static getInstance(){return e.instance||(e.instance=new e),e.instance}initialize(){try{if(this.initialized)return;this.scheduleFlush(),globalThis.addEventListener("unload",(()=>{this.flush()})),this.initialized=!0}catch(e){l(e)}}addEvent(e){if(e&&this.initialized)try{const t=this.config.getConfig()?.options?.beforeSend,n=this.config.getConfig()?.options?.enrichEvent;if(t&&!t(e))return;n&&(e=n(e)),this.events.push(e);const i=this.config.getConfig()?.options?.batchSize||100;this.events.length>=i&&!w.includes(e.type)&&this.flush()}catch(e){l(e)}}flush(){try{if(!this.events?.length||!this.initialized)return;if(!this.config.getConfig()?.cluster)return void this.logger.log("[events-pool.flush] skipping flush: no cluster");this.transporter.send({sessionAttributes:this.getSessionAttributes(),events:this.events}),this.events=[],this.scheduleFlush()}catch(e){l(e)}}async flushSync(){try{if(!this.events?.length||!this.initialized)return;if(!this.config.getConfig()?.cluster)return void this.logger.log("[events-pool.flush] skipping flush: no cluster");await this.transporter.send({sessionAttributes:this.getSessionAttributes(),events:this.events}),this.events=[]}catch(e){l(e)}}scheduleFlush(){try{null!==this.timeoutId&&(g.clearTimeout(this.timeoutId),this.timeoutId=null);const e=this.config.getConfig()?.options?.batchTimeout;if(!e)return;this.timeoutId=g.setTimeout((()=>{this.timeoutId=null,this.flush()}),e)}catch(e){l(e)}}detectBrowser(){const e=navigator.userAgent;let t="unknown",n="unknown";const i=navigator.platform||"unknown",s=/Mobile|Android|iPhone|iPad|iPod/i.test(e);return/Edg/.test(e)?(t="Edge",n=e.match(/Edg\/([\d.]+)/)?.[1]||n):/Chrome/.test(e)&&!/Chromium/.test(e)?(t="Chrome",n=e.match(/Chrome\/([\d.]+)/)?.[1]||n):/Firefox/.test(e)?(t="Firefox",n=e.match(/Firefox\/([\d.]+)/)?.[1]||n):/Safari/.test(e)&&!/Chrome/.test(e)?(t="Safari",n=e.match(/Version\/([\d.]+)/)?.[1]||n):/Trident/.test(e)?(t="Internet Explorer",n=/rv:([^)]+)\)/i.test(e)?e.match(/rv:([^)]+)\)/i)?.[1]||n:e.match(/MSIE ([^;]+)/)?.[1]||n):/OPR/.test(e)&&(t="Opera",n=e.match(/OPR\/([\d.]+)/)?.[1]||n),{name:t,version:n,platform:i,language:navigator.language,mobile:s}}getSessionAttributes(){const e=this.detectBrowser();return{cluster:this.config.getConfig()?.cluster||"",env:this.config.getConfig()?.environment||"",namespace:this.config.getConfig()?.namespace||"",session_id:this.config.getSessionId(),user:this.config.getConfig()?.userIdentifier||{},"service.name":this.config.getConfig()?.appId,userAgent:navigator.userAgent,browser:e}}};T.instance=null;var N=T,S=class{constructor(){this.logger=a.getInstance(),this.eventsPool=N.getInstance()}};function C({text:e,maxLength:t=1e4}){return e?e.length<=t||"string"!=typeof e?e:e.substring(0,t):""}var L=class extends S{constructor(){super(...arguments),this.eventHandlers=[],this.capturedEvents=["click","change","keydown","select","submit"],this.config=h.getInstance(),this.getShouldMaskText=e=>{const t=this.config.getConfig(),n=t?.options?.maskFields||[],i=t?.options?.enableMasking||!1;return(["password"===e.target?.type,e.target?.id?.toLowerCase().includes("password"),e.target?.id?.toLowerCase().includes("credit-card"),e.target?.id?.toLowerCase().includes("cc"),e.target?.className?.toLowerCase().includes("cc"),e.target?.className?.toLowerCase().includes("credit-card"),e.target?.className?.toLowerCase().includes("credit-card"),e.target?.hasAttribute("data-private")].some((e=>e))||n.some((t=>e.target?.id?.toLowerCase().includes(t))))&&i},this.getKeyCode=e=>{if(e instanceof KeyboardEvent&&e.code&&"Dead"!==e.key){const t=this.getShouldMaskText({target:e.target});return t||t?"*":e.key}return""},this.getText=e=>{const t=e.target,n=this.config.getConfig();return n?.options?.enableMasking||!1?"*":C({text:t.innerText||""})},this.getSelector=e=>e.target instanceof Element&&this.generateSelector(e.target)||"",this.getCoordinates=e=>{if({mouseup:!0,mousedown:!0,mousemove:!0,mouseover:!0}[e.type]){const{clientX:t,clientY:n}=e||{};return{clientX:t,clientY:n}}return null}}initialize(){try{this.logger.log("[dom-events-listener.initialize] called"),this.capturedEvents?.forEach((e=>{const t=e=>{try{this.handleEvent(e)}catch(e){l(e)}};this.eventHandlers.push({type:e,handler:t}),g?.addEventListener(e,t)}))}catch(e){l(e)}}destroy(){this.eventHandlers.forEach((({type:e,handler:t})=>{global?.removeEventListener?.(e,t)})),this.eventHandlers=[]}handleEvent(e){try{if(!y())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){l(e)}}buildEvent(e){const t=this.getSelector(e),n=this.getCoordinates(e),i=e.target,s=this.getKeyCode(e),r=this.getText(e);this.logger.log("[dom-events-listener.buildEvent] called");return b({type:"dom.event",attributes:{dom_event_selector:t,dom_event_key_code:s,dom_event_type:e.type,dom_event_coordinates:n||{clientX:0,clientY:0},dom_event_target:{id:i.id,tagName:i.tagName,className:i.className,text:r}}})}queueEvent(e){try{this.logger.log("[dom-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){l(e)}}generateSelector(e,t={}){if(!e||!e.nodeType||e.nodeType!==Node.ELEMENT_NODE)return"";const n=t.root||document.body||document.documentElement,i=t.maxAttempts||10,s=t.priorityAttributes||["id","class","name","aria-label","type","title","alt"];if("html"===e.tagName?.toLowerCase())return"html";let r="",a=0,o=e;const l=[];for(;o&&o!==n&&o!==document.documentElement&&a<i;){let e=o.tagName?.toLowerCase()||"";try{const t=o.getAttribute("id");if(t&&/^[a-zA-Z][\w-]*$/.test(t))return`#${t}`;if(o.classList?.length){const t=Array.from(o.classList).filter((e=>e&&"string"==typeof e)).map((e=>`.${e}`));t.length&&(e+=t.join(""))}for(const t of s)if("id"!==t&&"class"!==t)try{const n=o.getAttribute(t);n&&(e+=`[${t}="${n.replace(/"/g,'\\"')}"]`)}catch(e){}}catch(t){e=o.tagName?.toLowerCase()||"*"}l.unshift(e||"*"),r=l.join(" > ");try{if(1===n.querySelectorAll(r).length)return r}catch(e){l.shift(),r=l.join(" > ")}try{o=o.parentElement}catch(e){break}a++}return r||"*"}},H=["log","info","warn","error","assert","trace"],q=class extends S{constructor(){super(...arguments),this.originalConsole=null,this.isInitialized=!1}initialize(){if(!this.isInitialized)try{this.originalConsole=this.captureConsoleMethods(),H.forEach((e=>{e in console&&(console[e]=(...t)=>{try{this.handleEvent(t,e)}catch(e){l(e)}finally{this.originalConsole?.[e]&&this.originalConsole[e](...t)}})})),this.isInitialized=!0}catch(e){l(e)}}destroy(){try{if(!this.isInitialized)return;H.forEach((e=>{this.originalConsole&&this.originalConsole[e]&&(console[e]=this.originalConsole[e])})),this.isInitialized=!1}catch(e){l(e)}}handleEvent(e,t){try{if(!y())return;const n=this.formatMessage(Array.isArray(e)?e:[e],t);if(!n||n?.includes("groundcoverIgnore"))return;const i=this.buildEvent({message:n,level:t});this.queueEvent(i)}catch(e){l(e)}}buildEvent({message:e,level:t}){return b({type:"log",attributes:{message:C({text:e}),level:t}})}queueEvent(e){try{this.logger.log("[logs-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){l(e)}}formatMessage(e,t){if(!Array.isArray(e))return String(e);try{return e.map((e=>{if(void 0===e)return"undefined";if(null===e)return"null";if("object"==typeof e){if(e instanceof Error)try{return"error"===t&&e.stack||e.toString()}catch{try{const t={name:e.name,message:e.message,stack:e.stack};return JSON.stringify(t)}catch{return Object.prototype.toString.call(e)}}try{return JSON.stringify(e)}catch{return Object.prototype.toString.call(e)}}return String(e)})).join(" ")}catch(e){return l(e),"[Error formatting console message]"}}captureConsoleMethods(){const e={};try{H.forEach((t=>{console&&"function"==typeof console[t]&&(e[t]=console[t].bind(console))}))}catch(e){l(e)}return e}};function z(e){try{if(null==e)return"";if("string"==typeof e)return e;if(e instanceof FormData)return"[form data]";if(e instanceof Blob)return"[blob data]";if(e instanceof ArrayBuffer)return"[arraybuffer data]";if("undefined"!=typeof Document){if(e instanceof Document)return"[document data]";const t=e;if(9===t?.nodeType)return"[document data]"}if(e instanceof URLSearchParams)try{return e.toString()}catch{return"[unreadable body]"}return Array.isArray(e)||"object"==typeof e?JSON.stringify(e):String(e)}catch(e){return l(`Failed to format body: ${e}`),"[unreadable body]"}}var R,_=class extends S{constructor(){super(...arguments),this.maxBodyLength=5e3,this.config=h.getInstance(),this.idGenerator=new u,this.handleEvent=e=>{try{if(this.shouldIgnoreRequest(e.url))return;if(!y())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){l(e)}},this.buildEvent=e=>{let t=e.url,n=e.url;this.logger.log("[network-events-listener.buildEvent] called",{event:e});try{t=new URL(e.url).pathname}catch(t){n=new URL(e.url,globalThis.location.href).href}this.logger.log("[network-events-listener.buildEvent] fullUrl",{fullUrl:n});const i=this.formatHeaders(e.request.headers),s=this.formatHeaders(e.response.headers),r=e.method?.toUpperCase()||"UNKNOWN",{traceId:a,spanId:o}=this.extractTraceIds(e.request.headers),l=C({text:e.request.body,maxLength:this.maxBodyLength}),d=C({text:e.response.body,maxLength:this.maxBodyLength}),c={type:"HTTP",operation:{name:r},resource_name:t,status:e.status?.toString(),subType:r,url:{full:n},http:{route:t,path:t,method:e.method,status:e.status?.toString(),request:{headers:i,method:e.method},response:{headers:s,status_code:e.status?.toString()}},error:e?.error?.type?{type:e.error?.type||"Unknown error"}:void 0,gc:{request:{body:l},response:{body:d}}},h={type:"network",timestamp:e?.timestamp&&!Number.isNaN(e.timestamp)?1e6*e.timestamp:void 0,end_timestamp:e?.end_time&&!Number.isNaN(e.end_time)?1e6*e.end_time:void 0,span_name:`${e.method} ${t}`,attributes:c};return a&&(h.traceId=a),o&&(h.spanId=o),b(h)}}async getResponseBody(e){let t;try{const n=e.clone().body;if(n){let e,i=n.getReader(),s=new TextDecoder,r="";for(;!(e=await i.read()).done;){let t=e.value;r+=s.decode(t)}t=r}else t=""}catch(e){t=`Unable to clone response: ${e}`}return t}initialize(){this.logger.log("[network-events-listener.initialize] called"),this.patchXHR(),this.patchFetch()}destroy(){globalThis.XMLHttpRequest.prototype.open=globalThis.XMLHttpRequest.prototype.open,globalThis.XMLHttpRequest.prototype.send=globalThis.XMLHttpRequest.prototype.send,globalThis.fetch=globalThis.fetch}shouldIgnoreRequest(e){try{const t=this.config.getConfig()?.getEndpoint();if(t&&e.includes(t))return!0;if([".tsx",".jsx",".css"].some((t=>e.toLowerCase().endsWith(t))))return!0;return(this.config.getConfig()?.options?.excludedUrls||[]).some((t=>{if(t instanceof RegExp)return t.test(e);if("string"==typeof t&&(t.includes("*")||t.includes("?"))){const n=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".");return new RegExp(n).test(e)}return e===t}))}catch(e){return l(e),!1}}queueEvent(e){try{this.logger.log("[network-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){l(e)}}patchXHR(){const e=this,t=globalThis.XMLHttpRequest.prototype.open,n=globalThis.XMLHttpRequest.prototype.send,i=globalThis.XMLHttpRequest.prototype.setRequestHeader;let s;globalThis.XMLHttpRequest.prototype.open=function(n,i,r=!0,a,o){if(s=Date.now(),e.shouldIgnoreRequest(i.toString()))return t.apply(this,[n,i,r,a,o]);const l=new URL(i.toString(),globalThis.location.href).href;return this._requestMethod=n,this._requestUrl=l,this._requestHeaders={},t.apply(this,[n,i,r,a,o])},globalThis.XMLHttpRequest.prototype.setRequestHeader=function(e,t){return this._requestHeaders&&(this._requestHeaders[e]=t),i.apply(this,[e,t])},globalThis.XMLHttpRequest.prototype.send=function(...t){const i=this._requestUrl?.toString();if(!i||e.shouldIgnoreRequest(i))return n.apply(this,t);if(e.shouldAddTraceHeader(i)){const t=e.config.getConfig(),n=e.getTraceIds();t?.options?.traceOrigin?.name&&e.addHeaderToXhrRequest({request:this,headerName:t.options.traceOrigin.name,headerValue:t.options.traceOrigin.value}),n&&(t?.options?.tracePropagationTraceIdHeaderName&&e.addHeaderToXhrRequest({request:this,headerName:t.options.tracePropagationTraceIdHeaderName,headerValue:n.decimalTraceId}),t?.options?.tracePropagationSpanIdHeaderName&&e.addHeaderToXhrRequest({request:this,headerName:t.options.tracePropagationSpanIdHeaderName,headerValue:n.decimalSpanId}),Boolean(t?.options?.tracePropagationHeaders)&&t?.options?.tracePropagationHeaders?.forEach((t=>{e.addHeaderToXhrRequest({request:this,headerName:t,headerValue:n.traceparent})})),t?.options?.tracePropagationHeaders?.length||e.addHeaderToXhrRequest({request:this,headerName:"traceparent",headerValue:n.traceparent}))}return this._requestBody=t[0]||"",this.addEventListener("load",(()=>{const t=Date.now(),n={};this.getAllResponseHeaders().split(/\r?\n/).forEach((e=>{const[t,i]=e.split(": ");t&&i&&(n[t.trim()]=i.trim())}));const i=z(this._requestBody),r=z(""===this.responseType||"text"===this.responseType?this.responseText:this.response),a={timestamp:s,end_time:t,method:this._requestMethod,url:this._requestUrl,body:i,status:this.status,request:{headers:this._requestHeaders||{},body:i},response:{headers:n,body:r}};e.handleEvent(a)})),n.apply(this,t)}}normalizeHeaders(e,t){try{const n=e?new Headers(e):new Headers;return t?(t instanceof Headers?t.forEach(((e,t)=>n.set(t,e))):Array.isArray(t)?new Headers(t).forEach(((e,t)=>n.set(t,e))):"object"==typeof t&&Object.entries(t).forEach((([e,t])=>n.set(e,t))),n):n}catch{return new Headers}}addTraceHeaders(e){const t=this.config.getConfig(),n=this.getTraceIds();if(t?.options?.traceOrigin?.name&&this.addHeaderToFetchRequest({init:e,headerName:t.options.traceOrigin.name,headerValue:t.options.traceOrigin.value}),!n)return;t?.options?.tracePropagationTraceIdHeaderName&&this.addHeaderToFetchRequest({init:e,headerName:t.options.tracePropagationTraceIdHeaderName,headerValue:n.decimalTraceId}),t?.options?.tracePropagationSpanIdHeaderName&&this.addHeaderToFetchRequest({init:e,headerName:t.options.tracePropagationSpanIdHeaderName,headerValue:n.decimalSpanId});const i=t?.options?.tracePropagationHeaders;(i?.length?i:["traceparent"]).forEach((t=>{this.addHeaderToFetchRequest({init:e,headerName:t,headerValue:n.traceparent})}))}extractHeadersRecord(e){const t={};return e instanceof Headers&&e.forEach(((e,n)=>{t[n]=e})),t}patchFetch(){const e=globalThis.fetch;globalThis.fetch=(...t)=>{const n=Date.now();let[i,s]=t;s={...s||{}},t[1]=s;const r=i instanceof Request,a=s?.method||"GET",o=s?.body||"",l=i instanceof Request?i.url:i.toString();if(this.shouldIgnoreRequest(l))return e.apply(globalThis,t);const d=this.shouldAddTraceHeader(l);s||(t[1]={},s=t[1]),s.headers=this.normalizeHeaders(r?i.headers:void 0,s.headers),d&&this.addTraceHeaders(s);const c=this.extractHeadersRecord(s.headers),h=z(o);return e.apply(globalThis,t).then((e=>{const t=Date.now(),i=e.clone(),s={};i.headers.forEach(((e,t)=>{s[t]=e}));const r={method:a,url:l,timestamp:n,body:h,status:i.status,end_time:t,request:{headers:c,body:h},response:{headers:s,body:""}};try{s["content-type"]?.includes("text/event-stream")?(r.response.body="[unreadable response body]",this.handleEvent(r)):this.getResponseBody(i).then((e=>{r.response.body=e,this.handleEvent(r)})).catch((e=>{r.response.body="[unreadable response body]",this.handleEvent(r),this.logger.log("[network-events-listener.patchFetch] error",{error:e})}))}catch(e){r.response.body="[unreadable response body]",this.handleEvent(r),this.logger.log("[network-events-listener.patchFetch] error",{error:e})}return e})).catch((e=>{const t=Date.now();let n="NetworkError";const i=e.message||"Unknown network error";e instanceof TypeError&&i.includes("Failed to fetch")?n="ERR_NETWORK_FAILURE":i.includes("Name not resolved")?n="ERR_NAME_NOT_RESOLVED":i.includes("Connection refused")&&(n="ERR_CONNECTION_REFUSED");const s={method:a,url:l,body:h,status:0,end_time:t,request:{headers:c,body:h},response:{headers:{},body:""},error:{type:n}};throw this.handleEvent(s),e}))}}formatHeaders(e){const t=["authorization","cookie","set-cookie"];return Object.entries(e)?.reduce(((e,[n,i])=>{const s=n.toLowerCase();return t.includes(s)||/(token|key|secret|password)/i.test(s)?e[n]="[REDACTED]":e[n]=C({text:i}),e}),{})}extractTraceIds(e){const t=this.config.getConfig();let n="",i="";if(t?.options?.tracePropagationTraceIdHeaderName){const i=e[t.options.tracePropagationTraceIdHeaderName];i&&"string"==typeof i&&(n=i)}if(t?.options?.tracePropagationSpanIdHeaderName){const n=e[t.options.tracePropagationSpanIdHeaderName];n&&"string"==typeof n&&(i=n)}if(!n||!i){const t=this.extractTraceparentHeader(e);if(t){const e=t.split("-");4===e.length&&"00"===e[0]&&(!n&&e[1]&&32===e[1].length&&(n=e[1]),!i&&e[2]&&16===e[2].length&&(i=e[2]))}}return{traceId:n,spanId:i}}extractTraceparentHeader(e){const t=this.config.getConfig();if(t?.options?.tracePropagationHeaders?.length)for(const n of t.options.tracePropagationHeaders){const t=e[n];if(t&&"string"==typeof t)return t}const n=e.traceparent;return n&&"string"==typeof n?n:""}getTraceIds(){const e=this.idGenerator.generateSpanId(),t=this.idGenerator.generateTraceId();let n,i;try{n=BigInt("0x"+t).toString(10),i=BigInt("0x"+e).toString(10)}catch(s){this.logger.log("[network-events-listener.getTraceIds] error",{error:s}),n=t,i=e}return{traceparent:`00-${t}-${e}-01`,traceId:t,spanId:e,decimalTraceId:n,decimalSpanId:i}}addHeaderToXhrRequest({request:e,headerName:t,headerValue:n}){if(this.logger.log("[network-events-listener.addHeaderToXhrRequest] called",{request:e,headerName:t,headerValue:n}),this.isValidHeaderName(t))try{e.setRequestHeader(t,n),e._requestHeaders[t]=n}catch(e){this.logger.log("[network-events-listener.addHeaderToXhrRequest] Error setting header",{error:e,headerName:t,headerValue:n})}else this.logger.log("[network-events-listener.addHeaderToXhrRequest] Invalid header name",{headerName:t})}addHeaderToFetchRequest({init:e,headerName:t,headerValue:n}){if(this.logger.log("[network-events-listener.addHeaderToFetchRequest] called",{init:e,headerName:t,headerValue:n}),this.isValidHeaderName(t))try{e.headers instanceof Headers?e.headers.set(t,n):e.headers={...e.headers,[t]:n}}catch(e){this.logger.log("[network-events-listener.addHeaderToFetchRequest] Error setting header",{error:e,headerName:t,headerValue:n})}else this.logger.log("[network-events-listener.addHeaderToFetchRequest] Invalid header name",{headerName:t})}isValidHeaderName(e){if(!e||"string"!=typeof e)return!1;return/^[a-zA-Z0-9!#$&'*+\-.^_`|~]+$/.test(e)}shouldAddTraceHeader(e){const t=this.config.getConfig();if(this.logger.log("[network-events-listener.shouldAddTraceHeader] called",{url:e,config:t}),!t?.options?.tracePropagationUrls?.length)return!1;const n=t.options.tracePropagationUrls?.some((t=>{const n=t.replace(/\*/g,".*"),i=new RegExp(`^${n}$`),s=e.startsWith("/")?new URL(e,globalThis.location.href).pathname:e;return i.test(s)}));return this.logger.log("[network-events-listener.shouldAddTraceHeader] result",{url:e,result:n}),n}},k=class extends S{constructor(){super(...arguments),this.handleEvent=(e,t)=>{this.logger.log("[errors-events-listener.handleEvent] called");try{let n;if(e instanceof Error)n=e,this.enhanceError(n);else if(e instanceof ErrorEvent){if(n=e.error||new Error(e.message||"Unknown error"),/Script error\.?/.test(n.message))return;this.enhanceError(n,e)}else{if(!(e instanceof PromiseRejectionEvent))return;n=this.createUnhandledRejectionError(e)}const i=this.buildEvent(n,t);this.queueEvent(i)}catch(e){l(e)}}}initialize(){g?.addEventListener("error",this.handleEvent),g?.addEventListener("unhandledrejection",this.handleEvent)}destroy(){g?.removeEventListener("error",this.handleEvent),g?.removeEventListener("unhandledrejection",this.handleEvent)}buildEvent(e,t){return b({type:"exception",attributes:{error_type:e.name||"Error",error_message:e.message||"Unknown error",error_stacktrace:this.buildStackTrace(e),error_fingerprint:`${e.name}:${C({text:e.message,maxLength:400})}`,error_handled:t?.handled||!1}})}queueEvent(e){try{this.logger.log("[errors-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){l(e)}}enhanceError(e,t){const{filename:n,lineno:i,colno:s}=t||{};n&&!e.fileName&&Object.defineProperty(e,"fileName",{value:n}),i&&!e.lineNumber&&Object.defineProperty(e,"lineNumber",{value:i}),s&&!e.columnNumber&&Object.defineProperty(e,"columnNumber",{value:s})}createUnhandledRejectionError(e){let t;if(e.reason instanceof Error)t=e.reason;else{const n="object"==typeof e.reason?JSON.stringify(e.reason,null,2):String(e.reason);t=new Error(n),t.name="UnhandledRejection",Object.defineProperty(t,"originalReason",{value:e.reason,enumerable:!1})}return t}buildStackTrace(e){if(!e)return[];try{return s.default.parse(e).map((e=>({filename:e.fileName||"unknown",function:e.functionName||"anonymous",lineno:e.lineNumber||0,colno:e.columnNumber||0})))}catch(e){return[]}}},x=class extends S{constructor({isEnabled:e}){if(super(),this.currentUrl="",this.originalPushState=null,this.originalReplaceState=null,this.isInitialized=!1,this.isAutomaticNavigationEnabled=!1,this.activeNavigation=null,this.popStateHandler=()=>{this.handleLocationChange()},this.hashChangeHandler=()=>{this.handleLocationChange()},this.isInBrowserEnvironment()&&e)try{this.isAutomaticNavigationEnabled=e,this.currentUrl=g.location.href,this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState}catch(e){l(e)}}isInBrowserEnvironment(){try{return void 0!==g&&void 0!==g.location&&void 0!==g.history&&"function"==typeof g.addEventListener}catch(e){return l(e),!1}}initialize(){try{if(this.logger.log("[navigation-listener.initialize] called"),!this.isInBrowserEnvironment()||!this.originalPushState||!this.originalReplaceState)return void this.logger.log("[navigation-listener.initialize] Browser environment not available, skipping initialization");if(!this.isAutomaticNavigationEnabled)return void this.logger.log("[navigation-listener.initialize] Automatic navigation is disabled, skipping initialization");const e=this.originalPushState,t=this.originalReplaceState;history.pushState=(...t)=>{const n=e.apply(history,t);return this.handleLocationChange(),n},history.replaceState=(...e)=>{const n=t.apply(history,e);return this.handleLocationChange(),n},g&&"function"==typeof g.addEventListener&&(g.addEventListener("popstate",this.popStateHandler),g.addEventListener("hashchange",this.hashChangeHandler)),this.isInitialized=!0}catch(e){l(e)}}destroy(){try{this.logger.log("[navigation-listener.destroy] called"),this.isInitialized&&this.originalPushState&&this.originalReplaceState&&(history.pushState=this.originalPushState,history.replaceState=this.originalReplaceState),g&&"function"==typeof g.removeEventListener&&(g.removeEventListener("popstate",this.popStateHandler),g.removeEventListener("hashchange",this.hashChangeHandler)),this.isInitialized=!1}catch(e){l(e)}}handleEvent(){try{this.logger.log("[navigation-listener.handleEvent] called");const e=this.buildEvent();this.queueEvent(e)}catch(e){l(e)}}buildEvent(){this.logger.log("[navigation-listener.buildEvent] called",g.location.href);return b({type:"navigation",attributes:{page_url:g.location.href,metadata:this.activeNavigation?.metadata,duration_ms:this.activeNavigation?.duration_ms||0,start_timestamp:this.activeNavigation?.startTime||0,end_timestamp:this.activeNavigation?.endTime||0}})}queueEvent(e){try{this.logger.log("[navigation-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){l(e)}}startNavigation(e){this.logger.log("[navigation-listener.startNavigation] called",e),this.activeNavigation={page_url:g.location.href,metadata:e,startTime:Date.now(),endTime:0,duration_ms:0}}endNavigation(e){this.logger.log("[navigation-listener.endNavigation] called",e),this.activeNavigation?(this.logger.log("[navigation-listener.endNavigation] active navigation",this.activeNavigation),this.activeNavigation.endTime=Date.now(),this.activeNavigation.duration_ms=this.activeNavigation.endTime-this.activeNavigation.startTime,this.handleEvent()):this.logger.log("[navigation-listener.endNavigation] no active navigation found")}handleLocationChange(){try{if(!this.isInitialized)return;if(this.logger.log("[navigation-listener.handleLocationChange] called"),this.currentUrl===g.location.href)return;let e,t;try{e=new URL(g.location.href),t=new URL(this.currentUrl)}catch(e){return void l(e)}const n=e=>e.startsWith("#/"),i=n(e.hash)||n(t.hash);(e.pathname!==t.pathname||i&&e.hash!==t.hash)&&(this.currentUrl=g.location.href,this.handleEvent())}catch(e){l(e)}}},P=class extends S{constructor(){super(),this.loadEventHandler=()=>{this.logger.log("load event"),this.handleEvent()}}initialize(){try{this.logger.log("[page-load-listener.initialize] called"),this.logger.log("globalThis",g),"complete"===g?.document?.readyState?(this.logger.log("Page already loaded, triggering event immediately"),this.handleEvent()):g?.addEventListener("load",this.loadEventHandler)}catch(e){this.logger.log("[page-load-listener.initialize] error",e),l(e)}}destroy(){g?.removeEventListener("load",this.loadEventHandler)}handleEvent(){try{this.logger.log("[page-load-listener.handleEvent] called");const e=this.buildEvent();this.queueEvent(e)}catch(e){l(e)}}buildEvent(){const e=performance.getEntriesByType("navigation")[0],t=e?e.loadEventEnd-e.startTime:0,n=performance.getEntriesByType("resource"),i={count:n.length,totalSize:0,totalDuration:0,byType:{}};n.forEach((e=>{const t=e,n=t.transferSize||0,s=t.duration,r=t.initiatorType;i.totalSize+=n,i.totalDuration+=s,i.byType[r]||(i.byType[r]={count:0,size:0,duration:0}),i.byType[r].count++,i.byType[r].size+=n,i.byType[r].duration+=s}));return b({type:"pageload",attributes:{page_url:g?.location?.href||"",page_load_time:t,page_referrer:g?.document?.referrer||"",page_resources:i}})}queueEvent(e){try{this.logger.log("[page-load-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){l(e)}}},M=class extends S{constructor(){super(...arguments),this.handleEvent=e=>{try{if(!y())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){l(e)}}}initialize(){n.onCLS(this.handleEvent),n.onLCP(this.handleEvent),n.onFCP(this.handleEvent),n.onTTFB(this.handleEvent),n.onINP(this.handleEvent)}destroy(){}buildEvent(e){return b({type:"performance",attributes:{performance_metric_name:e.name,performance_metric_value:e.value,performance_metric_id:e.id,performance_metric_navigation_type:e.navigationType||""}})}queueEvent(e){try{this.logger.log("[performance-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){l(e)}}},A=class{constructor(){this.logger=a.getInstance(),this.eventsPool=N.getInstance(),this.configManager=h.getInstance(),this.logEventsListener=null,this.domEventsListener=null,this.errorsEventsListener=null,this.networkEventsListener=null,this.navigationListener=null,this.performanceListener=null,this.pageLoadListener=null}instrument(){this.logger.log("[instrumentation-manager.instrument] called");const e=this.configManager.getConfig(),t=e?.options?.enabledEvents,n=!t||0===t.length,i=[];(n||t?.includes("pageload"))&&(this.pageLoadListener=new P,this.pageLoadListener.initialize(),i.push("pageload")),(n||t?.includes("dom"))&&(this.domEventsListener=new L,this.domEventsListener.initialize(),i.push("dom")),(n||t?.includes("logs"))&&(this.logEventsListener=new q,this.logEventsListener.initialize(),i.push("logs")),(n||t?.includes("exceptions"))&&(this.errorsEventsListener=new k,this.errorsEventsListener.initialize(),i.push("exceptions")),(n||t?.includes("network"))&&(this.networkEventsListener=new _,this.networkEventsListener.initialize(),i.push("network")),(n||t?.includes("performance"))&&(this.performanceListener=new M,this.performanceListener.initialize(),i.push("performance")),this.navigationListener=new x({isEnabled:n||t?.includes("navigation")}),this.navigationListener.initialize(),i.push("navigation"),this.logger.log("[instrumentation-manager.instrument] initialized listeners based on config:",i)}sendCustomEvent(e){this.logger.log("[instrumentation-manager.sendCustomEvent] called",e);try{const t=b({type:"custom",attributes:{custom_event_name:e?.event,custom_event_attributes:e?.attributes}});this.eventsPool.addEvent(t)}catch(e){l(e)}}captureException(e){try{this.logger.log("[instrumentation-manager.captureException] called",e),this.errorsEventsListener?.handleEvent(e,{handled:!0})}catch(e){l(e)}}isNavigationTrackingEnabled(){const e=this.configManager.getConfig();return e?.options?.enabledEvents?.includes("navigation")||0===e?.options?.enabledEvents?.length}startNavigation(e){this.logger.log("[instrumentation-manager.startNavigation] called",e),this.isNavigationTrackingEnabled()?this.logger.log("[instrumentation-manager.startNavigation] startNavigation called while navigation tracking is enabled. Ignoring. If you wish to track navigations manually, please disable navigation tracking via the enabledEvents array in the config."):this.navigationListener?.startNavigation(e)}endNavigation(e){this.logger.log("[instrumentation-manager.endNavigation] called",e),this.isNavigationTrackingEnabled()?this.logger.log("[instrumentation-manager.endNavigation] endNavigation called while navigation tracking is enabled. Ignoring. If you wish to track navigations manually, please disable navigation tracking via the enabledEvents array in the config."):this.navigationListener?.endNavigation(e)}uninstrument(){this.domEventsListener?.destroy(),this.logEventsListener?.destroy(),this.errorsEventsListener?.destroy(),this.networkEventsListener?.destroy(),this.navigationListener?.destroy(),this.performanceListener?.destroy(),this.pageLoadListener?.destroy()}},D="gcSample",U=class{constructor(e){this.initialized=!1,this.logger=a.initialize({debug:e.options?.debug||!1,prefix:"[groundcover]"}),this.logger.log("[session-manager] initialize called"),this.instrumentationManager=new A,this.idGenerator=new u;if(!this.getSamplingDecision(e.options?.sessionSampleRate))return void this.logger.log("[session-manager] session is not sampled");if(this.initialized)return void this.logger.log("[session-manager] SDK already initialized");const t=h.getInstance();t.initialize(e);N.getInstance().initialize();const n=e.sessionId,i=t.getSessionId();n?(t.setSessionId(n),this.logger.log("[session-manager] using provided sessionId:",n)):i||t.setSessionId(this.idGenerator.generateId()),this.instrumentationManager.instrument(),this.initialized=!0}getSamplingDecision(e){try{if(!e||1===e)return!0;const t=globalThis.sessionStorage?.getItem(D);if(t){const e="1"===t;return this.logger.log("[session-manager] using stored sampling decision:",e),e}const n=!e||Math.random()<e;return globalThis?.sessionStorage?.setItem(D,n?"1":"0"),this.logger.log("[session-manager] stored new sampling decision:",n),n}catch(t){this.logger.log("[session-manager] session storage access failed:",t);const n=!e||Math.random()<e;return this.logger.log("[session-manager] using fallback sampling decision:",n),n}}identifyUser(e){if(this.logger.log("[session-manager] identifyUser called"),!this.initialized)return void this.logger.log("[session-manager] cannot identify user: SDK not initialized");h.getInstance().updateConfig({userIdentifier:e})}updateConfig(e){if(!this.initialized)return void this.logger.log("[session-manager] cannot update config: SDK not initialized");h.getInstance().updateConfig(e)}sendCustomEvent(e){this.initialized?this.instrumentationManager.sendCustomEvent(e):this.logger.log("[session-manager] cannot send custom event: SDK not initialized")}startNavigation(e){this.initialized?this.instrumentationManager.startNavigation(e):this.logger.log("[session-manager] cannot start navigation: SDK not initialized")}endNavigation(e){this.initialized?this.instrumentationManager.endNavigation(e):this.logger.log("[session-manager] cannot end navigation: SDK not initialized")}captureException(e){this.initialized?this.instrumentationManager.captureException(e):this.logger.log("[session-manager] Cannot capture exception: SDK not initialized")}async setSessionId(e){if(this.logger.log("[session-manager] setSessionId called"),this.initialized)try{const t=N.getInstance();await t.flushSync();const n=e||this.idGenerator.generateId();h.getInstance().setSessionId(n),this.logger.log("[session-manager] session ID set successfully:",n)}catch(e){this.logger.log("[session-manager] failed to set session ID:",e)}else this.logger.log("[session-manager] cannot set session ID: SDK not initialized")}destroy(){this.initialized&&(this.instrumentationManager.uninstrument(),globalThis.sessionStorage?.removeItem("gcId"),this.initialized=!1)}};var O={init:function(e){try{R=new U({cluster:e?.cluster||"",environment:e?.environment||"",namespace:e?.namespace,dsn:e?.dsn||"",appId:e?.appId||"",userIdentifier:e?.userIdentifier,apiKey:e?.apiKey||"",options:e?.options,sessionId:e?.sessionId})}catch(e){l(e)}},identifyUser:function(e){R?R.identifyUser(e):console.warn("[groundcover] identifyUser: groundcover is not initialized. please call init() first")},sendCustomEvent:function(e){R&&R.sendCustomEvent(e)},captureException:function(e){R&&R.captureException(e)},updateConfig:function(e){R&&R.updateConfig(e)},startNavigation:function(e){R?R.startNavigation(e):console.warn("[groundcover] startNavigation: groundcover is not initialized. please call init() first")},endNavigation:function(e){R?R.endNavigation(e):console.warn("[groundcover] endNavigation: groundcover is not initialized. please call init() first")},setSessionId:async function(e){if(R)try{await R.setSessionId(e)}catch(e){console.error("[groundcover] setSessionId: failed to set session ID:",e)}else console.warn("[groundcover] setSessionId: groundcover is not initialized. please call init() first")}};if("undefined"!=typeof window&&!window.groundcover)try{window.groundcover=O}catch(e){console.warn("[groundcover] Failed to expose groundcover on window:",e)}var j=O;module.exports=j;
1
+ "use strict";var e=require("fflate"),t=require("error-stack-parser"),n=require("web-vitals"),i=require("rrweb");function s(e){return e&&e.__esModule?e:{default:e}}var r=s(t),a=console.log.bind(console),o=class e{constructor(){this.isDebugEnabled=!1,this.prefix=""}static initialize(t){return e.instance||(e.instance=new e),t&&(e.instance.isDebugEnabled=t.debug??!1,e.instance.prefix=t.prefix??""),e.instance}static getInstance(t){return e?.instance||e.initialize(t)}formatMessage(e){return`[${(new Date).toISOString()}] ${this.prefix} ${e}`}log(e,...t){this.isDebugEnabled&&a(this.formatMessage(e),...t)}updateConfig(e){this.isDebugEnabled=e.debug??this.isDebugEnabled,this.prefix=e.prefix??this.prefix}},l=o.getInstance();function d(e){l.log("[error-handler.handleError] called",e,{groundcoverIgnore:!0})}var c={batchSize:10,batchTimeout:1e4,eventSampleRate:1,sessionSampleRate:1,environment:"development",debug:!1,enableCompression:!0,maskFields:[],enableMasking:!1,enabledEvents:[],tracePropagationUrls:[],tracePropagationHeaders:[],tracePropagationTraceIdHeaderName:"",tracePropagationSpanIdHeaderName:"",traceOrigin:{name:"",value:""}},g=class{constructor(e){this.dsn=e?.dsn||"",this.appId=e?.appId||"",this.cluster=e?.cluster||"",this.apiKey=e?.apiKey||"",this.environment=e?.environment||"",this.namespace=e?.namespace||"",this.userIdentifier=e?.userIdentifier||null,this.options={...c,...e?.options||{}}}getEndpoint(){return this.dsn?.startsWith("http")?this.dsn:`https://${this.dsn}`}updateConfig(e){e.options&&(this.options={...this.options,...e.options}),e.userIdentifier&&(this.userIdentifier={...this.userIdentifier,...e.userIdentifier}),e.appId&&(this.appId=e.appId),e.dsn&&(this.dsn=e.dsn),e.apiKey&&(this.apiKey=e.apiKey),e.cluster&&(this.cluster=e.cluster),e.environment&&(this.environment=e.environment),e.namespace&&(this.namespace=e.namespace)}},h=class e{constructor(){this.config=null,this.logger=o.getInstance(),this.sessionId=null}static getInstance(){return e.instance||(e.instance=new e),e.instance}initialize(e){this.config||(this.config=new g(e))}getConfig(){return this.config?this.config:(this.logger.log("[config-manager] configuration not initialized"),null)}getSessionId(){if(this.sessionId)return this.sessionId;const e=globalThis?.sessionStorage?.getItem("gcId");return e||""}setSessionId(e){this.sessionId=e,globalThis?.sessionStorage?.setItem("gcId",e)}updateConfig(e){this.logger.log("[config-manager] updateConfig called"),this.config?(e&&(this.logger.log("[config-manager] updating options"),this.config.updateConfig(e)),e?.userIdentifier&&(this.logger.log("[config-manager] updating user identifier"),this.config.userIdentifier={...this.config.userIdentifier,...e.userIdentifier})):this.logger.log("[config-manager] configuration not initialized")}},u="object"==typeof globalThis?globalThis:"object"==typeof self?self:"object"==typeof window?window:"object"==typeof global?global:{},p=class{constructor(){this.generateTraceId=f(16),this.generateSpanId=f(8),this.generateId=f(16)}},m=Array(32);function f(e){return function(){for(let t=0;t<2*e;t++)m[t]=Math.floor(16*Math.random())+48,m[t]>=58&&(m[t]+=39);return String.fromCharCode.apply(null,m.slice(0,2*e))}}var v=h.getInstance(),y=new p,E=o.getInstance();function b(){const e=v?.getConfig()?.options?.eventSampleRate;return!(void 0!==e&&!Number.isNaN(e))||Math.random()<=e}function I(e,t="",n=new WeakSet){if(n.has(e))return{[t||"circular_reference"]:"[Circular]"};n.add(e);try{return Object.entries(e).reduce(((e,[i,s])=>{const r=t?`${t}.${i}`:i;return"object"==typeof s&&null!==s?Array.isArray(s)?e[r]=s.map(((e,t)=>"object"==typeof e&&null!==e?I(e,`${r}[${t}]`,n):e)):Object.assign(e,I(s,r,n)):e[r]=s,e}),{})}catch(e){return E.log("[events-processors.formatEventObject] Error formatting event object",e),{[t||"format_error"]:"[Error formatting object]"}}finally{n.delete(e)}}function w(e){const t=1e6*Date.now(),n=y.generateId(),i=e.spanId||y.generateSpanId(),s=e.traceId||y.generateTraceId(),r=e.parentSpanId||"",a=I(e.attributes||{}),o=function(){const e=u?.location;return e?{path:e.hash&&!e.hash.match(/^#[a-z0-9-]+$/i)&&e.hash.startsWith("#/")?e.hash:e.pathname,url:e.href,title:u?.document?.title||""}:{path:"",url:"",title:u?.document?.title||""}}(),l={type:e.type,id:n,spanId:i,parentSpanId:r,traceId:s,attributes:{...a,location:o}};return e.span_name&&(l.span_name=e.span_name),"network"===e.type?(l.start_timestamp=e.timestamp||t,l.end_timestamp=e?.end_timestamp):l.timestamp=t,l}var S=class{constructor(){this.logger=o.getInstance(),this.config=h.getInstance()}compress(t){const n=this.config.getConfig();if(!n?.options?.enableCompression)return{data:(new TextEncoder).encode(t),isCompressed:!1};try{const n=e.strToU8(t);return{data:e.gzipSync(n),isCompressed:!0}}catch(e){return{data:(new TextEncoder).encode(t),isCompressed:!1}}}async send(e){const t=this.config.getConfig();if(t)try{t?.options?.debug&&this.logger.log("Sending batch:",e,{groundcoverIgnore:!0});const n=t.apiKey,i=this.buildEndpoint();if(!n)return void this.logger.log("No API key found");const s=JSON.stringify(e),{data:r,isCompressed:a}=this.compress(s);fetch(i,{method:"POST",headers:{"Content-Type":"application/json",apikey:n,"Content-Encoding":a?"gzip":""},body:r}).catch((e=>{this.logger.log("Network error while sending batch:",e,{groundcoverIgnore:!0})}))}catch(e){t.options.debug&&this.logger.log("Failed to send batch:",e,{groundcoverIgnore:!0})}}buildEndpoint(){const e=this.config.getConfig();if(!e)return"";const{dsn:t}=e;return`${t}/json/rum`}},T=["navigation","dom.event"],N=class e{constructor(){this.events=[],this.timeoutId=null,this.config=h.getInstance(),this.logger=o.getInstance(),this.initialized=!1,this.transporter=new S}static getInstance(){return e.instance||(e.instance=new e),e.instance}initialize(){try{if(this.initialized)return;this.scheduleFlush(),globalThis.addEventListener("unload",(()=>{this.flush()})),this.initialized=!0}catch(e){d(e)}}addEvent(e){if(e&&this.initialized)try{const t=this.config.getConfig()?.options?.beforeSend,n=this.config.getConfig()?.options?.enrichEvent;if(t&&!t(e))return;n&&(e=n(e)),this.events.push(e);const i=this.config.getConfig()?.options?.batchSize||100;this.events.length>=i&&!T.includes(e.type)&&this.flush()}catch(e){d(e)}}flush(){try{if(!this.events?.length||!this.initialized)return;if(!this.config.getConfig()?.cluster)return void this.logger.log("[events-pool.flush] skipping flush: no cluster");this.transporter.send({sessionAttributes:this.getSessionAttributes(),events:this.events}),this.events=[],this.scheduleFlush()}catch(e){d(e)}}async flushSync(){try{if(!this.events?.length||!this.initialized)return;if(!this.config.getConfig()?.cluster)return void this.logger.log("[events-pool.flush] skipping flush: no cluster");await this.transporter.send({sessionAttributes:this.getSessionAttributes(),events:this.events}),this.events=[]}catch(e){d(e)}}scheduleFlush(){try{null!==this.timeoutId&&(u.clearTimeout(this.timeoutId),this.timeoutId=null);const e=this.config.getConfig()?.options?.batchTimeout;if(!e)return;this.timeoutId=u.setTimeout((()=>{this.timeoutId=null,this.flush()}),e)}catch(e){d(e)}}detectBrowser(){const e=navigator.userAgent;let t="unknown",n="unknown";const i=navigator.platform||"unknown",s=/Mobile|Android|iPhone|iPad|iPod/i.test(e);return/Edg/.test(e)?(t="Edge",n=e.match(/Edg\/([\d.]+)/)?.[1]||n):/Chrome/.test(e)&&!/Chromium/.test(e)?(t="Chrome",n=e.match(/Chrome\/([\d.]+)/)?.[1]||n):/Firefox/.test(e)?(t="Firefox",n=e.match(/Firefox\/([\d.]+)/)?.[1]||n):/Safari/.test(e)&&!/Chrome/.test(e)?(t="Safari",n=e.match(/Version\/([\d.]+)/)?.[1]||n):/Trident/.test(e)?(t="Internet Explorer",n=/rv:([^)]+)\)/i.test(e)?e.match(/rv:([^)]+)\)/i)?.[1]||n:e.match(/MSIE ([^;]+)/)?.[1]||n):/OPR/.test(e)&&(t="Opera",n=e.match(/OPR\/([\d.]+)/)?.[1]||n),{name:t,version:n,platform:i,language:navigator.language,mobile:s}}getSessionAttributes(){const e=this.detectBrowser();return{cluster:this.config.getConfig()?.cluster||"",env:this.config.getConfig()?.environment||"",namespace:this.config.getConfig()?.namespace||"",session_id:this.config.getSessionId(),user:this.config.getConfig()?.userIdentifier||{},"service.name":this.config.getConfig()?.appId,userAgent:navigator.userAgent,browser:e}}};N.instance=null;var R=N,L=class{constructor(){this.logger=o.getInstance(),this.eventsPool=R.getInstance()}};function C({text:e,maxLength:t=1e4}){return e?e.length<=t||"string"!=typeof e?e:e.substring(0,t):""}var z=class extends L{constructor(){super(...arguments),this.eventHandlers=[],this.capturedEvents=["click","change","keydown","select","submit"],this.config=h.getInstance(),this.getShouldMaskText=e=>{const t=this.config.getConfig(),n=t?.options?.maskFields||[],i=t?.options?.enableMasking||!1;return(["password"===e.target?.type,e.target?.id?.toLowerCase().includes("password"),e.target?.id?.toLowerCase().includes("credit-card"),e.target?.id?.toLowerCase().includes("cc"),e.target?.className?.toLowerCase().includes("cc"),e.target?.className?.toLowerCase().includes("credit-card"),e.target?.className?.toLowerCase().includes("credit-card"),e.target?.hasAttribute("data-private")].some((e=>e))||n.some((t=>e.target?.id?.toLowerCase().includes(t))))&&i},this.getKeyCode=e=>{if(e instanceof KeyboardEvent&&e.code&&"Dead"!==e.key){const t=this.getShouldMaskText({target:e.target});return t||t?"*":e.key}return""},this.getText=e=>{const t=e.target,n=this.config.getConfig();return n?.options?.enableMasking||!1?"*":C({text:t.innerText||""})},this.getSelector=e=>e.target instanceof Element&&this.generateSelector(e.target)||"",this.getCoordinates=e=>{if({mouseup:!0,mousedown:!0,mousemove:!0,mouseover:!0}[e.type]){const{clientX:t,clientY:n}=e||{};return{clientX:t,clientY:n}}return null}}initialize(){try{this.logger.log("[dom-events-listener.initialize] called"),this.capturedEvents?.forEach((e=>{const t=e=>{try{this.handleEvent(e)}catch(e){d(e)}};this.eventHandlers.push({type:e,handler:t}),u?.addEventListener(e,t)}))}catch(e){d(e)}}destroy(){this.eventHandlers.forEach((({type:e,handler:t})=>{global?.removeEventListener?.(e,t)})),this.eventHandlers=[]}handleEvent(e){try{if(!b())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){d(e)}}buildEvent(e){const t=this.getSelector(e),n=this.getCoordinates(e),i=e.target,s=this.getKeyCode(e),r=this.getText(e);this.logger.log("[dom-events-listener.buildEvent] called");return w({type:"dom.event",attributes:{dom_event_selector:t,dom_event_key_code:s,dom_event_type:e.type,dom_event_coordinates:n||{clientX:0,clientY:0},dom_event_target:{id:i.id,tagName:i.tagName,className:i.className,text:r}}})}queueEvent(e){try{this.logger.log("[dom-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){d(e)}}generateSelector(e,t={}){if(!e||!e.nodeType||e.nodeType!==Node.ELEMENT_NODE)return"";const n=t.root||document.body||document.documentElement,i=t.maxAttempts||10,s=t.priorityAttributes||["id","class","name","aria-label","type","title","alt"];if("html"===e.tagName?.toLowerCase())return"html";let r="",a=0,o=e;const l=[];for(;o&&o!==n&&o!==document.documentElement&&a<i;){let e=o.tagName?.toLowerCase()||"";try{const t=o.getAttribute("id");if(t&&/^[a-zA-Z][\w-]*$/.test(t))return`#${t}`;if(o.classList?.length){const t=Array.from(o.classList).filter((e=>e&&"string"==typeof e)).map((e=>`.${e}`));t.length&&(e+=t.join(""))}for(const t of s)if("id"!==t&&"class"!==t)try{const n=o.getAttribute(t);n&&(e+=`[${t}="${n.replace(/"/g,'\\"')}"]`)}catch(e){}}catch(t){e=o.tagName?.toLowerCase()||"*"}l.unshift(e||"*"),r=l.join(" > ");try{if(1===n.querySelectorAll(r).length)return r}catch(e){l.shift(),r=l.join(" > ")}try{o=o.parentElement}catch(e){break}a++}return r||"*"}},H=["log","info","warn","error","assert","trace"],q=class extends L{constructor(){super(...arguments),this.originalConsole=null,this.isInitialized=!1}initialize(){if(!this.isInitialized)try{this.originalConsole=this.captureConsoleMethods(),H.forEach((e=>{e in console&&(console[e]=(...t)=>{try{this.handleEvent(t,e)}catch(e){d(e)}finally{this.originalConsole?.[e]&&this.originalConsole[e](...t)}})})),this.isInitialized=!0}catch(e){d(e)}}destroy(){try{if(!this.isInitialized)return;H.forEach((e=>{this.originalConsole&&this.originalConsole[e]&&(console[e]=this.originalConsole[e])})),this.isInitialized=!1}catch(e){d(e)}}handleEvent(e,t){try{if(!b())return;const n=this.formatMessage(Array.isArray(e)?e:[e],t);if(!n||n?.includes("groundcoverIgnore"))return;const i=this.buildEvent({message:n,level:t});this.queueEvent(i)}catch(e){d(e)}}buildEvent({message:e,level:t}){return w({type:"log",attributes:{message:C({text:e}),level:t}})}queueEvent(e){try{this.logger.log("[logs-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){d(e)}}formatMessage(e,t){if(!Array.isArray(e))return String(e);try{return e.map((e=>{if(void 0===e)return"undefined";if(null===e)return"null";if("object"==typeof e){if(e instanceof Error)try{return"error"===t&&e.stack||e.toString()}catch{try{const t={name:e.name,message:e.message,stack:e.stack};return JSON.stringify(t)}catch{return Object.prototype.toString.call(e)}}try{return JSON.stringify(e)}catch{return Object.prototype.toString.call(e)}}return String(e)})).join(" ")}catch(e){return d(e),"[Error formatting console message]"}}captureConsoleMethods(){const e={};try{H.forEach((t=>{console&&"function"==typeof console[t]&&(e[t]=console[t].bind(console))}))}catch(e){d(e)}return e}};function _(e){try{if(null==e)return"";if("string"==typeof e)return e;if(e instanceof FormData)return"[form data]";if(e instanceof Blob)return"[blob data]";if(e instanceof ArrayBuffer)return"[arraybuffer data]";if("undefined"!=typeof Document){if(e instanceof Document)return"[document data]";const t=e;if(9===t?.nodeType)return"[document data]"}if(e instanceof URLSearchParams)try{return e.toString()}catch{return"[unreadable body]"}return Array.isArray(e)||"object"==typeof e?JSON.stringify(e):String(e)}catch(e){return d(`Failed to format body: ${e}`),"[unreadable body]"}}var k=class extends L{constructor(){super(...arguments),this.maxBodyLength=5e3,this.config=h.getInstance(),this.idGenerator=new p,this.handleEvent=e=>{try{if(this.shouldIgnoreRequest(e.url))return;if(!b())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){d(e)}},this.buildEvent=e=>{let t=e.url,n=e.url;this.logger.log("[network-events-listener.buildEvent] called",{event:e});try{t=new URL(e.url).pathname}catch(t){n=new URL(e.url,globalThis.location.href).href}this.logger.log("[network-events-listener.buildEvent] fullUrl",{fullUrl:n});const i=this.formatHeaders(e.request.headers),s=this.formatHeaders(e.response.headers),r=e.method?.toUpperCase()||"UNKNOWN",{traceId:a,spanId:o}=this.extractTraceIds(e.request.headers),l=C({text:e.request.body,maxLength:this.maxBodyLength}),d=C({text:e.response.body,maxLength:this.maxBodyLength}),c={type:"HTTP",operation:{name:r},resource_name:t,status:e.status?.toString(),subType:r,url:{full:n},http:{route:t,path:t,method:e.method,status:e.status?.toString(),request:{headers:i,method:e.method},response:{headers:s,status_code:e.status?.toString()}},error:e?.error?.type?{type:e.error?.type||"Unknown error"}:void 0,gc:{request:{body:l},response:{body:d}}},g={type:"network",timestamp:e?.timestamp&&!Number.isNaN(e.timestamp)?1e6*e.timestamp:void 0,end_timestamp:e?.end_time&&!Number.isNaN(e.end_time)?1e6*e.end_time:void 0,span_name:`${e.method} ${t}`,attributes:c};return a&&(g.traceId=a),o&&(g.spanId=o),w(g)}}async getResponseBody(e){let t;try{const n=e.clone().body;if(n){let e,i=n.getReader(),s=new TextDecoder,r="";for(;!(e=await i.read()).done;){let t=e.value;r+=s.decode(t)}t=r}else t=""}catch(e){t=`Unable to clone response: ${e}`}return t}initialize(){this.logger.log("[network-events-listener.initialize] called"),this.patchXHR(),this.patchFetch()}destroy(){globalThis.XMLHttpRequest.prototype.open=globalThis.XMLHttpRequest.prototype.open,globalThis.XMLHttpRequest.prototype.send=globalThis.XMLHttpRequest.prototype.send,globalThis.fetch=globalThis.fetch}shouldIgnoreRequest(e){try{const t=this.config.getConfig()?.getEndpoint();if(t&&e.includes(t))return!0;if([".tsx",".jsx",".css"].some((t=>e.toLowerCase().endsWith(t))))return!0;return(this.config.getConfig()?.options?.excludedUrls||[]).some((t=>{if(t instanceof RegExp)return t.test(e);if("string"==typeof t&&(t.includes("*")||t.includes("?"))){const n=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".");return new RegExp(n).test(e)}return e===t}))}catch(e){return d(e),!1}}queueEvent(e){try{this.logger.log("[network-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){d(e)}}patchXHR(){const e=this,t=globalThis.XMLHttpRequest.prototype.open,n=globalThis.XMLHttpRequest.prototype.send,i=globalThis.XMLHttpRequest.prototype.setRequestHeader;let s;globalThis.XMLHttpRequest.prototype.open=function(n,i,r=!0,a,o){if(s=Date.now(),e.shouldIgnoreRequest(i.toString()))return t.apply(this,[n,i,r,a,o]);const l=new URL(i.toString(),globalThis.location.href).href;return this._requestMethod=n,this._requestUrl=l,this._requestHeaders={},t.apply(this,[n,i,r,a,o])},globalThis.XMLHttpRequest.prototype.setRequestHeader=function(e,t){return this._requestHeaders&&(this._requestHeaders[e]=t),i.apply(this,[e,t])},globalThis.XMLHttpRequest.prototype.send=function(...t){const i=this._requestUrl?.toString();if(!i||e.shouldIgnoreRequest(i))return n.apply(this,t);if(e.shouldAddTraceHeader(i)){const t=e.config.getConfig(),n=e.getTraceIds();t?.options?.traceOrigin?.name&&e.addHeaderToXhrRequest({request:this,headerName:t.options.traceOrigin.name,headerValue:t.options.traceOrigin.value}),n&&(t?.options?.tracePropagationTraceIdHeaderName&&e.addHeaderToXhrRequest({request:this,headerName:t.options.tracePropagationTraceIdHeaderName,headerValue:n.decimalTraceId}),t?.options?.tracePropagationSpanIdHeaderName&&e.addHeaderToXhrRequest({request:this,headerName:t.options.tracePropagationSpanIdHeaderName,headerValue:n.decimalSpanId}),Boolean(t?.options?.tracePropagationHeaders)&&t?.options?.tracePropagationHeaders?.forEach((t=>{e.addHeaderToXhrRequest({request:this,headerName:t,headerValue:n.traceparent})})),t?.options?.tracePropagationHeaders?.length||e.addHeaderToXhrRequest({request:this,headerName:"traceparent",headerValue:n.traceparent}))}return this._requestBody=t[0]||"",this.addEventListener("load",(()=>{const t=Date.now(),n={};this.getAllResponseHeaders().split(/\r?\n/).forEach((e=>{const[t,i]=e.split(": ");t&&i&&(n[t.trim()]=i.trim())}));const i=_(this._requestBody),r=_(""===this.responseType||"text"===this.responseType?this.responseText:this.response),a={timestamp:s,end_time:t,method:this._requestMethod,url:this._requestUrl,body:i,status:this.status,request:{headers:this._requestHeaders||{},body:i},response:{headers:n,body:r}};e.handleEvent(a)})),n.apply(this,t)}}normalizeHeaders(e,t){try{const n=e?new Headers(e):new Headers;return t?(t instanceof Headers?t.forEach(((e,t)=>n.set(t,e))):Array.isArray(t)?new Headers(t).forEach(((e,t)=>n.set(t,e))):"object"==typeof t&&Object.entries(t).forEach((([e,t])=>n.set(e,t))),n):n}catch{return new Headers}}addTraceHeaders(e){const t=this.config.getConfig(),n=this.getTraceIds();if(t?.options?.traceOrigin?.name&&this.addHeaderToFetchRequest({init:e,headerName:t.options.traceOrigin.name,headerValue:t.options.traceOrigin.value}),!n)return;t?.options?.tracePropagationTraceIdHeaderName&&this.addHeaderToFetchRequest({init:e,headerName:t.options.tracePropagationTraceIdHeaderName,headerValue:n.decimalTraceId}),t?.options?.tracePropagationSpanIdHeaderName&&this.addHeaderToFetchRequest({init:e,headerName:t.options.tracePropagationSpanIdHeaderName,headerValue:n.decimalSpanId});const i=t?.options?.tracePropagationHeaders;(i?.length?i:["traceparent"]).forEach((t=>{this.addHeaderToFetchRequest({init:e,headerName:t,headerValue:n.traceparent})}))}extractHeadersRecord(e){const t={};return e instanceof Headers&&e.forEach(((e,n)=>{t[n]=e})),t}patchFetch(){const e=globalThis.fetch;globalThis.fetch=(...t)=>{const n=Date.now();let[i,s]=t;s={...s||{}},t[1]=s;const r=i instanceof Request,a=s?.method||"GET",o=s?.body||"",l=i instanceof Request?i.url:i.toString();if(this.shouldIgnoreRequest(l))return e.apply(globalThis,t);const d=this.shouldAddTraceHeader(l);s||(t[1]={},s=t[1]),s.headers=this.normalizeHeaders(r?i.headers:void 0,s.headers),d&&this.addTraceHeaders(s);const c=this.extractHeadersRecord(s.headers),g=_(o);return e.apply(globalThis,t).then((e=>{const t=Date.now(),i=e.clone(),s={};i.headers.forEach(((e,t)=>{s[t]=e}));const r={method:a,url:l,timestamp:n,body:g,status:i.status,end_time:t,request:{headers:c,body:g},response:{headers:s,body:""}};try{s["content-type"]?.includes("text/event-stream")?(r.response.body="[unreadable response body]",this.handleEvent(r)):this.getResponseBody(i).then((e=>{r.response.body=e,this.handleEvent(r)})).catch((e=>{r.response.body="[unreadable response body]",this.handleEvent(r),this.logger.log("[network-events-listener.patchFetch] error",{error:e})}))}catch(e){r.response.body="[unreadable response body]",this.handleEvent(r),this.logger.log("[network-events-listener.patchFetch] error",{error:e})}return e})).catch((e=>{const t=Date.now();let n="NetworkError";const i=e.message||"Unknown network error";e instanceof TypeError&&i.includes("Failed to fetch")?n="ERR_NETWORK_FAILURE":i.includes("Name not resolved")?n="ERR_NAME_NOT_RESOLVED":i.includes("Connection refused")&&(n="ERR_CONNECTION_REFUSED");const s={method:a,url:l,body:g,status:0,end_time:t,request:{headers:c,body:g},response:{headers:{},body:""},error:{type:n}};throw this.handleEvent(s),e}))}}formatHeaders(e){const t=["authorization","cookie","set-cookie"];return Object.entries(e)?.reduce(((e,[n,i])=>{const s=n.toLowerCase();return t.includes(s)||/(token|key|secret|password)/i.test(s)?e[n]="[REDACTED]":e[n]=C({text:i}),e}),{})}extractTraceIds(e){const t=this.config.getConfig();let n="",i="";if(t?.options?.tracePropagationTraceIdHeaderName){const i=e[t.options.tracePropagationTraceIdHeaderName];i&&"string"==typeof i&&(n=i)}if(t?.options?.tracePropagationSpanIdHeaderName){const n=e[t.options.tracePropagationSpanIdHeaderName];n&&"string"==typeof n&&(i=n)}if(!n||!i){const t=this.extractTraceparentHeader(e);if(t){const e=t.split("-");4===e.length&&"00"===e[0]&&(!n&&e[1]&&32===e[1].length&&(n=e[1]),!i&&e[2]&&16===e[2].length&&(i=e[2]))}}return{traceId:n,spanId:i}}extractTraceparentHeader(e){const t=this.config.getConfig();if(t?.options?.tracePropagationHeaders?.length)for(const n of t.options.tracePropagationHeaders){const t=e[n];if(t&&"string"==typeof t)return t}const n=e.traceparent;return n&&"string"==typeof n?n:""}getTraceIds(){const e=this.idGenerator.generateSpanId(),t=this.idGenerator.generateTraceId();let n,i;try{n=BigInt("0x"+t).toString(10),i=BigInt("0x"+e).toString(10)}catch(s){this.logger.log("[network-events-listener.getTraceIds] error",{error:s}),n=t,i=e}return{traceparent:`00-${t}-${e}-01`,traceId:t,spanId:e,decimalTraceId:n,decimalSpanId:i}}addHeaderToXhrRequest({request:e,headerName:t,headerValue:n}){if(this.logger.log("[network-events-listener.addHeaderToXhrRequest] called",{request:e,headerName:t,headerValue:n}),this.isValidHeaderName(t))try{e.setRequestHeader(t,n),e._requestHeaders[t]=n}catch(e){this.logger.log("[network-events-listener.addHeaderToXhrRequest] Error setting header",{error:e,headerName:t,headerValue:n})}else this.logger.log("[network-events-listener.addHeaderToXhrRequest] Invalid header name",{headerName:t})}addHeaderToFetchRequest({init:e,headerName:t,headerValue:n}){if(this.logger.log("[network-events-listener.addHeaderToFetchRequest] called",{init:e,headerName:t,headerValue:n}),this.isValidHeaderName(t))try{e.headers instanceof Headers?e.headers.set(t,n):e.headers={...e.headers,[t]:n}}catch(e){this.logger.log("[network-events-listener.addHeaderToFetchRequest] Error setting header",{error:e,headerName:t,headerValue:n})}else this.logger.log("[network-events-listener.addHeaderToFetchRequest] Invalid header name",{headerName:t})}isValidHeaderName(e){if(!e||"string"!=typeof e)return!1;return/^[a-zA-Z0-9!#$&'*+\-.^_`|~]+$/.test(e)}shouldAddTraceHeader(e){const t=this.config.getConfig();if(this.logger.log("[network-events-listener.shouldAddTraceHeader] called",{url:e,config:t}),!t?.options?.tracePropagationUrls?.length)return!1;const n=t.options.tracePropagationUrls?.some((t=>{const n=t.replace(/\*/g,".*"),i=new RegExp(`^${n}$`),s=e.startsWith("/")?new URL(e,globalThis.location.href).pathname:e;return i.test(s)}));return this.logger.log("[network-events-listener.shouldAddTraceHeader] result",{url:e,result:n}),n}},x=class extends L{constructor(){super(...arguments),this.handleEvent=(e,t)=>{this.logger.log("[errors-events-listener.handleEvent] called");try{let n;if(e instanceof Error)n=e,this.enhanceError(n);else if(e instanceof ErrorEvent){if(n=e.error||new Error(e.message||"Unknown error"),/Script error\.?/.test(n.message))return;this.enhanceError(n,e)}else{if(!(e instanceof PromiseRejectionEvent))return;n=this.createUnhandledRejectionError(e)}const i=this.buildEvent(n,t);this.queueEvent(i)}catch(e){d(e)}}}initialize(){u?.addEventListener("error",this.handleEvent),u?.addEventListener("unhandledrejection",this.handleEvent)}destroy(){u?.removeEventListener("error",this.handleEvent),u?.removeEventListener("unhandledrejection",this.handleEvent)}buildEvent(e,t){return w({type:"exception",attributes:{error_type:e.name||"Error",error_message:e.message||"Unknown error",error_stacktrace:this.buildStackTrace(e),error_fingerprint:`${e.name}:${C({text:e.message,maxLength:400})}`,error_handled:t?.handled||!1,error_metadata:t?.metadata}})}queueEvent(e){try{this.logger.log("[errors-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){d(e)}}enhanceError(e,t){const{filename:n,lineno:i,colno:s}=t||{};n&&!e.fileName&&Object.defineProperty(e,"fileName",{value:n}),i&&!e.lineNumber&&Object.defineProperty(e,"lineNumber",{value:i}),s&&!e.columnNumber&&Object.defineProperty(e,"columnNumber",{value:s})}createUnhandledRejectionError(e){let t;if(e.reason instanceof Error)t=e.reason;else{const n="object"==typeof e.reason?JSON.stringify(e.reason,null,2):String(e.reason);t=new Error(n),t.name="UnhandledRejection",Object.defineProperty(t,"originalReason",{value:e.reason,enumerable:!1})}return t}buildStackTrace(e){if(!e)return[];try{return r.default.parse(e).map((e=>({filename:e.fileName||"unknown",function:e.functionName||"anonymous",lineno:e.lineNumber||0,colno:e.columnNumber||0})))}catch(e){return[]}}},P=class extends L{constructor({isEnabled:e}){if(super(),this.currentUrl="",this.originalPushState=null,this.originalReplaceState=null,this.isInitialized=!1,this.isAutomaticNavigationEnabled=!1,this.activeNavigation=null,this.popStateHandler=()=>{this.handleLocationChange()},this.hashChangeHandler=()=>{this.handleLocationChange()},this.isInBrowserEnvironment()&&e)try{this.isAutomaticNavigationEnabled=e,this.currentUrl=u.location.href,this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState}catch(e){d(e)}}isInBrowserEnvironment(){try{return void 0!==u&&void 0!==u.location&&void 0!==u.history&&"function"==typeof u.addEventListener}catch(e){return d(e),!1}}initialize(){try{if(this.logger.log("[navigation-listener.initialize] called"),!this.isInBrowserEnvironment()||!this.originalPushState||!this.originalReplaceState)return void this.logger.log("[navigation-listener.initialize] Browser environment not available, skipping initialization");if(!this.isAutomaticNavigationEnabled)return void this.logger.log("[navigation-listener.initialize] Automatic navigation is disabled, skipping initialization");const e=this.originalPushState,t=this.originalReplaceState;history.pushState=(...t)=>{const n=e.apply(history,t);return this.handleLocationChange(),n},history.replaceState=(...e)=>{const n=t.apply(history,e);return this.handleLocationChange(),n},u&&"function"==typeof u.addEventListener&&(u.addEventListener("popstate",this.popStateHandler),u.addEventListener("hashchange",this.hashChangeHandler)),this.isInitialized=!0}catch(e){d(e)}}destroy(){try{this.logger.log("[navigation-listener.destroy] called"),this.isInitialized&&this.originalPushState&&this.originalReplaceState&&(history.pushState=this.originalPushState,history.replaceState=this.originalReplaceState),u&&"function"==typeof u.removeEventListener&&(u.removeEventListener("popstate",this.popStateHandler),u.removeEventListener("hashchange",this.hashChangeHandler)),this.isInitialized=!1}catch(e){d(e)}}handleEvent(){try{this.logger.log("[navigation-listener.handleEvent] called");const e=this.buildEvent();this.queueEvent(e)}catch(e){d(e)}}buildEvent(){this.logger.log("[navigation-listener.buildEvent] called",u.location.href);return w({type:"navigation",attributes:{page_url:u.location.href,metadata:this.activeNavigation?.metadata,duration_ms:this.activeNavigation?.duration_ms||0,start_timestamp:this.activeNavigation?.startTime||0,end_timestamp:this.activeNavigation?.endTime||0}})}queueEvent(e){try{this.logger.log("[navigation-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){d(e)}}startNavigation(e){this.logger.log("[navigation-listener.startNavigation] called",e),this.activeNavigation={page_url:u.location.href,metadata:e,startTime:Date.now(),endTime:0,duration_ms:0}}endNavigation(e){this.logger.log("[navigation-listener.endNavigation] called",e),this.activeNavigation?(this.logger.log("[navigation-listener.endNavigation] active navigation",this.activeNavigation),this.activeNavigation.endTime=Date.now(),this.activeNavigation.duration_ms=this.activeNavigation.endTime-this.activeNavigation.startTime,this.handleEvent()):this.logger.log("[navigation-listener.endNavigation] no active navigation found")}handleLocationChange(){try{if(!this.isInitialized)return;if(this.logger.log("[navigation-listener.handleLocationChange] called"),this.currentUrl===u.location.href)return;let e,t;try{e=new URL(u.location.href),t=new URL(this.currentUrl)}catch(e){return void d(e)}const n=e=>e.startsWith("#/"),i=n(e.hash)||n(t.hash);(e.pathname!==t.pathname||i&&e.hash!==t.hash)&&(this.currentUrl=u.location.href,this.handleEvent())}catch(e){d(e)}}},M=class extends L{constructor(){super(),this.loadEventHandler=()=>{this.logger.log("load event"),this.handleEvent()}}initialize(){try{this.logger.log("[page-load-listener.initialize] called"),this.logger.log("globalThis",u),"complete"===u?.document?.readyState?(this.logger.log("Page already loaded, triggering event immediately"),this.handleEvent()):u?.addEventListener("load",this.loadEventHandler)}catch(e){this.logger.log("[page-load-listener.initialize] error",e),d(e)}}destroy(){u?.removeEventListener("load",this.loadEventHandler)}handleEvent(){try{this.logger.log("[page-load-listener.handleEvent] called");const e=this.buildEvent();this.queueEvent(e)}catch(e){d(e)}}buildEvent(){const e=performance.getEntriesByType("navigation")[0],t=e?e.loadEventEnd-e.startTime:0,n=performance.getEntriesByType("resource"),i={count:n.length,totalSize:0,totalDuration:0,byType:{}};n.forEach((e=>{const t=e,n=t.transferSize||0,s=t.duration,r=t.initiatorType;i.totalSize+=n,i.totalDuration+=s,i.byType[r]||(i.byType[r]={count:0,size:0,duration:0}),i.byType[r].count++,i.byType[r].size+=n,i.byType[r].duration+=s}));return w({type:"pageload",attributes:{page_url:u?.location?.href||"",page_load_time:t,page_referrer:u?.document?.referrer||"",page_resources:i}})}queueEvent(e){try{this.logger.log("[page-load-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){d(e)}}},A=class extends L{constructor(){super(...arguments),this.handleEvent=e=>{try{if(!b())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){d(e)}}}initialize(){n.onCLS(this.handleEvent),n.onLCP(this.handleEvent),n.onFCP(this.handleEvent),n.onTTFB(this.handleEvent),n.onINP(this.handleEvent)}destroy(){}buildEvent(e){return w({type:"performance",attributes:{performance_metric_name:e.name,performance_metric_value:e.value,performance_metric_id:e.id,performance_metric_navigation_type:e.navigationType||""}})}queueEvent(e){try{this.logger.log("[performance-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){d(e)}}};function D(e){try{return btoa(encodeURIComponent(JSON.stringify(e)))}catch(e){throw d(e),new Error(`Failed to convert to base64: ${e instanceof Error?e.message:String(e)}`)}}var U,j=class{constructor(){this.logger=o.getInstance(),this.eventsPool=R.getInstance(),this.stopFn=null,this.isRecording=!1,this.events=[],this.startTime=0,this.batchSize=10}initialize(){this.logger.log("[session-replay-listener] initialize called"),this.isRecording?this.logger.log("[session-replay-listener] already recording"):this.startRecording()}startRecording(){try{this.startTime=Date.now(),this.events=[],this.isRecording=!0,this.stopFn=i.record({emit:e=>{if(this.isRecording)try{if(this.events.push({type:e.type,data:e.data,timestamp:e.timestamp||Date.now()}),this.events.length>=this.batchSize)try{this.sendBatch()}catch(e){d(e),this.logger.log("[session-replay-listener] failed to send batch in emit callback:",e)}}catch(e){d(e),this.logger.log("[session-replay-listener] failed to process event in emit callback:",e)}}})||null,this.logger.log("[session-replay-listener] started recording")}catch(e){d(e),this.logger.log("[session-replay-listener] failed to start recording:",e),this.isRecording=!1}}sendBatch(){if(0!==this.events.length)try{const e=[...this.events],t=w({type:"replay",attributes:{replay_data:{events:D(e)}}});this.eventsPool.addEvent(t),this.events=[],this.logger.log("[session-replay-listener] sent batch with",e.length,"events")}catch(e){d(e),this.logger.log("[session-replay-listener] failed to send batch:",e)}}stopRecording(){if(this.isRecording&&this.stopFn)try{this.stopFn(),this.isRecording=!1;const e=this.events.length;if(e>0)try{const t=w({type:"replay",attributes:{replay_data:{events:D(this.events)}}});this.eventsPool.addEvent(t),this.logger.log("[session-replay-listener] sent final replay event with",e,"events")}catch(e){d(e),this.logger.log("[session-replay-listener] failed to encode and send final replay event:",e)}this.stopFn=null}catch(e){d(e),this.logger.log("[session-replay-listener] failed to stop recording:",e)}}destroy(){this.stopRecording()}},O=class{constructor(){this.logger=o.getInstance(),this.eventsPool=R.getInstance(),this.configManager=h.getInstance(),this.logEventsListener=null,this.domEventsListener=null,this.errorsEventsListener=null,this.networkEventsListener=null,this.navigationListener=null,this.performanceListener=null,this.pageLoadListener=null,this.sessionReplayListener=null}instrument(){this.logger.log("[instrumentation-manager.instrument] called");const e=this.configManager.getConfig(),t=e?.options?.enabledEvents,n=!t||0===t.length,i=[];(n||t?.includes("pageload"))&&(this.pageLoadListener=new M,this.pageLoadListener.initialize(),i.push("pageload")),(n||t?.includes("dom"))&&(this.domEventsListener=new z,this.domEventsListener.initialize(),i.push("dom")),(n||t?.includes("logs"))&&(this.logEventsListener=new q,this.logEventsListener.initialize(),i.push("logs")),(n||t?.includes("exceptions"))&&(this.errorsEventsListener=new x,this.errorsEventsListener.initialize(),i.push("exceptions")),(n||t?.includes("network"))&&(this.networkEventsListener=new k,this.networkEventsListener.initialize(),i.push("network")),(n||t?.includes("performance"))&&(this.performanceListener=new A,this.performanceListener.initialize(),i.push("performance")),this.navigationListener=new P({isEnabled:n||t?.includes("navigation")}),this.navigationListener.initialize(),i.push("navigation"),this.logger.log("[instrumentation-manager.instrument] initialized listeners based on config:",i)}sendCustomEvent(e){this.logger.log("[instrumentation-manager.sendCustomEvent] called",e);try{const t=w({type:"custom",attributes:{custom_event_name:e?.event,custom_event_attributes:e?.attributes}});this.eventsPool.addEvent(t)}catch(e){d(e)}}captureException(e,t){try{this.logger.log("[instrumentation-manager.captureException] called",e),this.errorsEventsListener?.handleEvent(e,{handled:!0,metadata:t})}catch(e){d(e)}}isNavigationTrackingEnabled(){const e=this.configManager.getConfig();return e?.options?.enabledEvents?.includes("navigation")||0===e?.options?.enabledEvents?.length}startNavigation(e){this.logger.log("[instrumentation-manager.startNavigation] called",e),this.isNavigationTrackingEnabled()?this.logger.log("[instrumentation-manager.startNavigation] startNavigation called while navigation tracking is enabled. Ignoring. If you wish to track navigations manually, please disable navigation tracking via the enabledEvents array in the config."):this.navigationListener?.startNavigation(e)}endNavigation(e){this.logger.log("[instrumentation-manager.endNavigation] called",e),this.isNavigationTrackingEnabled()?this.logger.log("[instrumentation-manager.endNavigation] endNavigation called while navigation tracking is enabled. Ignoring. If you wish to track navigations manually, please disable navigation tracking via the enabledEvents array in the config."):this.navigationListener?.endNavigation(e)}startReplayRecording(){this.sessionReplayListener?this.logger.log("[instrumentation-manager] replay recording already started"):(this.sessionReplayListener=new j,this.sessionReplayListener.initialize(),this.logger.log("[instrumentation-manager] started replay recording"))}stopReplayRecording(){this.sessionReplayListener?(this.sessionReplayListener.stopRecording(),this.sessionReplayListener=null):this.logger.log("[instrumentation-manager] cannot stop replay recording: replay listener not initialized")}uninstrument(){this.domEventsListener?.destroy(),this.logEventsListener?.destroy(),this.errorsEventsListener?.destroy(),this.networkEventsListener?.destroy(),this.navigationListener?.destroy(),this.performanceListener?.destroy(),this.pageLoadListener?.destroy(),this.sessionReplayListener?.destroy()}},F="gcSample",$=class{constructor(e){this.initialized=!1,this.logger=o.initialize({debug:e.options?.debug||!1,prefix:"[groundcover]"}),this.logger.log("[session-manager] initialize called"),this.instrumentationManager=new O,this.idGenerator=new p;if(!this.getSamplingDecision(e.options?.sessionSampleRate))return void this.logger.log("[session-manager] session is not sampled");if(this.initialized)return void this.logger.log("[session-manager] SDK already initialized");const t=h.getInstance();t.initialize(e);R.getInstance().initialize();const n=e.sessionId,i=t.getSessionId();n?(t.setSessionId(n),this.logger.log("[session-manager] using provided sessionId:",n)):i||t.setSessionId(this.idGenerator.generateId()),this.instrumentationManager.instrument(),this.initialized=!0}getSamplingDecision(e){try{if(!e||1===e)return!0;const t=globalThis.sessionStorage?.getItem(F);if(t){const e="1"===t;return this.logger.log("[session-manager] using stored sampling decision:",e),e}const n=!e||Math.random()<e;return globalThis?.sessionStorage?.setItem(F,n?"1":"0"),this.logger.log("[session-manager] stored new sampling decision:",n),n}catch(t){this.logger.log("[session-manager] session storage access failed:",t);const n=!e||Math.random()<e;return this.logger.log("[session-manager] using fallback sampling decision:",n),n}}identifyUser(e){if(this.logger.log("[session-manager] identifyUser called"),!this.initialized)return void this.logger.log("[session-manager] cannot identify user: SDK not initialized");h.getInstance().updateConfig({userIdentifier:e})}updateConfig(e){if(!this.initialized)return void this.logger.log("[session-manager] cannot update config: SDK not initialized");h.getInstance().updateConfig(e)}sendCustomEvent(e){this.initialized?this.instrumentationManager.sendCustomEvent(e):this.logger.log("[session-manager] cannot send custom event: SDK not initialized")}startNavigation(e){this.initialized?this.instrumentationManager.startNavigation(e):this.logger.log("[session-manager] cannot start navigation: SDK not initialized")}endNavigation(e){this.initialized?this.instrumentationManager.endNavigation(e):this.logger.log("[session-manager] cannot end navigation: SDK not initialized")}captureException(e,t){this.initialized?this.instrumentationManager.captureException(e,t):this.logger.log("[session-manager] Cannot capture exception: SDK not initialized")}async setSessionId(e){if(this.logger.log("[session-manager] setSessionId called"),this.initialized)try{const t=R.getInstance();await t.flushSync();const n=e||this.idGenerator.generateId();h.getInstance().setSessionId(n),this.logger.log("[session-manager] session ID set successfully:",n)}catch(e){this.logger.log("[session-manager] failed to set session ID:",e)}else this.logger.log("[session-manager] cannot set session ID: SDK not initialized")}startReplayRecording(){this.initialized?this.instrumentationManager.startReplayRecording():this.logger.log("[session-manager] cannot start replay recording: SDK not initialized")}stopReplayRecording(){this.initialized?this.instrumentationManager.stopReplayRecording():this.logger.log("[session-manager] cannot stop replay recording: SDK not initialized")}destroy(){this.initialized&&(this.instrumentationManager.uninstrument(),globalThis.sessionStorage?.removeItem("gcId"),this.initialized=!1)}};var X={init:function(e){try{U=new $({cluster:e?.cluster||"",environment:e?.environment||"",namespace:e?.namespace,dsn:e?.dsn||"",appId:e?.appId||"",userIdentifier:e?.userIdentifier,apiKey:e?.apiKey||"",options:e?.options,sessionId:e?.sessionId})}catch(e){d(e)}},identifyUser:function(e){U?U.identifyUser(e):console.warn("[groundcover] identifyUser: groundcover is not initialized. please call init() first")},sendCustomEvent:function(e){U&&U.sendCustomEvent(e)},captureException:function(e,t){U&&U.captureException(e,t)},updateConfig:function(e){U&&U.updateConfig(e)},startNavigation:function(e){U?U.startNavigation(e):console.warn("[groundcover] startNavigation: groundcover is not initialized. please call init() first")},endNavigation:function(e){U?U.endNavigation(e):console.warn("[groundcover] endNavigation: groundcover is not initialized. please call init() first")},setSessionId:async function(e){if(U)try{await U.setSessionId(e)}catch(e){console.error("[groundcover] setSessionId: failed to set session ID:",e)}else console.warn("[groundcover] setSessionId: groundcover is not initialized. please call init() first")},startReplayRecording:function(){U?U.startReplayRecording():console.warn("[groundcover] startReplayRecording: groundcover is not initialized. please call init() first")},stopReplayRecording:function(){U?U.stopReplayRecording():console.warn("[groundcover] stopReplayRecording: groundcover is not initialized. please call init() first")}};if("undefined"!=typeof window&&!window.groundcover)try{window.groundcover=X}catch(e){console.warn("[groundcover] Failed to expose groundcover on window:",e)}var B=X;module.exports=B;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{strToU8 as e,gzipSync as t}from"fflate";import n from"error-stack-parser";import{onCLS as i,onLCP as s,onFCP as r,onTTFB as a,onINP as o}from"web-vitals";var l=console.log.bind(console),d=class e{constructor(){this.isDebugEnabled=!1,this.prefix=""}static initialize(t){return e.instance||(e.instance=new e),t&&(e.instance.isDebugEnabled=t.debug??!1,e.instance.prefix=t.prefix??""),e.instance}static getInstance(t){return e?.instance||e.initialize(t)}formatMessage(e){return`[${(new Date).toISOString()}] ${this.prefix} ${e}`}log(e,...t){this.isDebugEnabled&&l(this.formatMessage(e),...t)}updateConfig(e){this.isDebugEnabled=e.debug??this.isDebugEnabled,this.prefix=e.prefix??this.prefix}},c=d.getInstance();function h(e){c.log("[error-handler.handleError] called",e,{groundcoverIgnore:!0})}var g={batchSize:10,batchTimeout:1e4,eventSampleRate:1,sessionSampleRate:1,environment:"development",debug:!1,enableCompression:!0,maskFields:[],enableMasking:!1,enabledEvents:[],tracePropagationUrls:[],tracePropagationHeaders:[],tracePropagationTraceIdHeaderName:"",tracePropagationSpanIdHeaderName:"",traceOrigin:{name:"",value:""}},u=class{constructor(e){this.dsn=e?.dsn||"",this.appId=e?.appId||"",this.cluster=e?.cluster||"",this.apiKey=e?.apiKey||"",this.environment=e?.environment||"",this.namespace=e?.namespace||"",this.userIdentifier=e?.userIdentifier||null,this.options={...g,...e?.options||{}}}getEndpoint(){return this.dsn?.startsWith("http")?this.dsn:`https://${this.dsn}`}updateConfig(e){e.options&&(this.options={...this.options,...e.options}),e.userIdentifier&&(this.userIdentifier={...this.userIdentifier,...e.userIdentifier}),e.appId&&(this.appId=e.appId),e.dsn&&(this.dsn=e.dsn),e.apiKey&&(this.apiKey=e.apiKey),e.cluster&&(this.cluster=e.cluster),e.environment&&(this.environment=e.environment),e.namespace&&(this.namespace=e.namespace)}},p=class e{constructor(){this.config=null,this.logger=d.getInstance(),this.sessionId=null}static getInstance(){return e.instance||(e.instance=new e),e.instance}initialize(e){this.config||(this.config=new u(e))}getConfig(){return this.config?this.config:(this.logger.log("[config-manager] configuration not initialized"),null)}getSessionId(){if(this.sessionId)return this.sessionId;const e=globalThis?.sessionStorage?.getItem("gcId");return e||""}setSessionId(e){this.sessionId=e,globalThis?.sessionStorage?.setItem("gcId",e)}updateConfig(e){this.logger.log("[config-manager] updateConfig called"),this.config?(e&&(this.logger.log("[config-manager] updating options"),this.config.updateConfig(e)),e?.userIdentifier&&(this.logger.log("[config-manager] updating user identifier"),this.config.userIdentifier={...this.config.userIdentifier,...e.userIdentifier})):this.logger.log("[config-manager] configuration not initialized")}},m="object"==typeof globalThis?globalThis:"object"==typeof self?self:"object"==typeof window?window:"object"==typeof global?global:{},f=class{constructor(){this.generateTraceId=y(16),this.generateSpanId=y(8),this.generateId=y(16)}},v=Array(32);function y(e){return function(){for(let t=0;t<2*e;t++)v[t]=Math.floor(16*Math.random())+48,v[t]>=58&&(v[t]+=39);return String.fromCharCode.apply(null,v.slice(0,2*e))}}var E=p.getInstance(),b=new f;function I(){const e=E?.getConfig()?.options?.eventSampleRate;return!(void 0!==e&&!Number.isNaN(e))||Math.random()<=e}function w(e,t=""){return Object.entries(e).reduce(((e,[n,i])=>{const s=t?`${t}.${n}`:n;return"object"==typeof i&&null!==i?Object.assign(e,w(i,s)):e[s]=i,e}),{})}function N(e){const t=1e6*Date.now(),n=b.generateId(),i=e.spanId||b.generateSpanId(),s=e.traceId||b.generateTraceId(),r=e.parentSpanId||"",a=w(e.attributes||{}),o=function(){const e=m?.location;return e?{path:e.hash&&!e.hash.match(/^#[a-z0-9-]+$/i)&&e.hash.startsWith("#/")?e.hash:e.pathname,url:e.href,title:m?.document?.title||""}:{path:"",url:"",title:m?.document?.title||""}}(),l={type:e.type,id:n,spanId:i,parentSpanId:r,traceId:s,attributes:{...a,location:o}};return e.span_name&&(l.span_name=e.span_name),"network"===e.type?(l.start_timestamp=e.timestamp||t,l.end_timestamp=e?.end_timestamp):l.timestamp=t,l}var T=class{constructor(){this.logger=d.getInstance(),this.config=p.getInstance()}compress(n){const i=this.config.getConfig();if(!i?.options?.enableCompression)return{data:(new TextEncoder).encode(n),isCompressed:!1};try{const i=e(n);return{data:t(i),isCompressed:!0}}catch(e){return{data:(new TextEncoder).encode(n),isCompressed:!1}}}async send(e){const t=this.config.getConfig();if(t)try{t?.options?.debug&&this.logger.log("Sending batch:",e,{groundcoverIgnore:!0});const n=t.apiKey,i=this.buildEndpoint();if(!n)return void this.logger.log("No API key found");const s=JSON.stringify(e),{data:r,isCompressed:a}=this.compress(s);fetch(i,{method:"POST",headers:{"Content-Type":"application/json",apikey:n,"Content-Encoding":a?"gzip":""},body:r}).catch((e=>{this.logger.log("Network error while sending batch:",e,{groundcoverIgnore:!0})}))}catch(e){t.options.debug&&this.logger.log("Failed to send batch:",e,{groundcoverIgnore:!0})}}buildEndpoint(){const e=this.config.getConfig();if(!e)return"";const{dsn:t}=e;return`${t}/json/rum`}},S=["navigation","dom.event"],H=class e{constructor(){this.events=[],this.timeoutId=null,this.config=p.getInstance(),this.logger=d.getInstance(),this.initialized=!1,this.transporter=new T}static getInstance(){return e.instance||(e.instance=new e),e.instance}initialize(){try{if(this.initialized)return;this.scheduleFlush(),globalThis.addEventListener("unload",(()=>{this.flush()})),this.initialized=!0}catch(e){h(e)}}addEvent(e){if(e&&this.initialized)try{const t=this.config.getConfig()?.options?.beforeSend,n=this.config.getConfig()?.options?.enrichEvent;if(t&&!t(e))return;n&&(e=n(e)),this.events.push(e);const i=this.config.getConfig()?.options?.batchSize||100;this.events.length>=i&&!S.includes(e.type)&&this.flush()}catch(e){h(e)}}flush(){try{if(!this.events?.length||!this.initialized)return;if(!this.config.getConfig()?.cluster)return void this.logger.log("[events-pool.flush] skipping flush: no cluster");this.transporter.send({sessionAttributes:this.getSessionAttributes(),events:this.events}),this.events=[],this.scheduleFlush()}catch(e){h(e)}}async flushSync(){try{if(!this.events?.length||!this.initialized)return;if(!this.config.getConfig()?.cluster)return void this.logger.log("[events-pool.flush] skipping flush: no cluster");await this.transporter.send({sessionAttributes:this.getSessionAttributes(),events:this.events}),this.events=[]}catch(e){h(e)}}scheduleFlush(){try{null!==this.timeoutId&&(m.clearTimeout(this.timeoutId),this.timeoutId=null);const e=this.config.getConfig()?.options?.batchTimeout;if(!e)return;this.timeoutId=m.setTimeout((()=>{this.timeoutId=null,this.flush()}),e)}catch(e){h(e)}}detectBrowser(){const e=navigator.userAgent;let t="unknown",n="unknown";const i=navigator.platform||"unknown",s=/Mobile|Android|iPhone|iPad|iPod/i.test(e);return/Edg/.test(e)?(t="Edge",n=e.match(/Edg\/([\d.]+)/)?.[1]||n):/Chrome/.test(e)&&!/Chromium/.test(e)?(t="Chrome",n=e.match(/Chrome\/([\d.]+)/)?.[1]||n):/Firefox/.test(e)?(t="Firefox",n=e.match(/Firefox\/([\d.]+)/)?.[1]||n):/Safari/.test(e)&&!/Chrome/.test(e)?(t="Safari",n=e.match(/Version\/([\d.]+)/)?.[1]||n):/Trident/.test(e)?(t="Internet Explorer",n=/rv:([^)]+)\)/i.test(e)?e.match(/rv:([^)]+)\)/i)?.[1]||n:e.match(/MSIE ([^;]+)/)?.[1]||n):/OPR/.test(e)&&(t="Opera",n=e.match(/OPR\/([\d.]+)/)?.[1]||n),{name:t,version:n,platform:i,language:navigator.language,mobile:s}}getSessionAttributes(){const e=this.detectBrowser();return{cluster:this.config.getConfig()?.cluster||"",env:this.config.getConfig()?.environment||"",namespace:this.config.getConfig()?.namespace||"",session_id:this.config.getSessionId(),user:this.config.getConfig()?.userIdentifier||{},"service.name":this.config.getConfig()?.appId,userAgent:navigator.userAgent,browser:e}}};H.instance=null;var L=H,C=class{constructor(){this.logger=d.getInstance(),this.eventsPool=L.getInstance()}};function z({text:e,maxLength:t=1e4}){return e?e.length<=t||"string"!=typeof e?e:e.substring(0,t):""}var q=class extends C{constructor(){super(...arguments),this.eventHandlers=[],this.capturedEvents=["click","change","keydown","select","submit"],this.config=p.getInstance(),this.getShouldMaskText=e=>{const t=this.config.getConfig(),n=t?.options?.maskFields||[],i=t?.options?.enableMasking||!1;return(["password"===e.target?.type,e.target?.id?.toLowerCase().includes("password"),e.target?.id?.toLowerCase().includes("credit-card"),e.target?.id?.toLowerCase().includes("cc"),e.target?.className?.toLowerCase().includes("cc"),e.target?.className?.toLowerCase().includes("credit-card"),e.target?.className?.toLowerCase().includes("credit-card"),e.target?.hasAttribute("data-private")].some((e=>e))||n.some((t=>e.target?.id?.toLowerCase().includes(t))))&&i},this.getKeyCode=e=>{if(e instanceof KeyboardEvent&&e.code&&"Dead"!==e.key){const t=this.getShouldMaskText({target:e.target});return t||t?"*":e.key}return""},this.getText=e=>{const t=e.target,n=this.config.getConfig();return n?.options?.enableMasking||!1?"*":z({text:t.innerText||""})},this.getSelector=e=>e.target instanceof Element&&this.generateSelector(e.target)||"",this.getCoordinates=e=>{if({mouseup:!0,mousedown:!0,mousemove:!0,mouseover:!0}[e.type]){const{clientX:t,clientY:n}=e||{};return{clientX:t,clientY:n}}return null}}initialize(){try{this.logger.log("[dom-events-listener.initialize] called"),this.capturedEvents?.forEach((e=>{const t=e=>{try{this.handleEvent(e)}catch(e){h(e)}};this.eventHandlers.push({type:e,handler:t}),m?.addEventListener(e,t)}))}catch(e){h(e)}}destroy(){this.eventHandlers.forEach((({type:e,handler:t})=>{global?.removeEventListener?.(e,t)})),this.eventHandlers=[]}handleEvent(e){try{if(!I())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){h(e)}}buildEvent(e){const t=this.getSelector(e),n=this.getCoordinates(e),i=e.target,s=this.getKeyCode(e),r=this.getText(e);this.logger.log("[dom-events-listener.buildEvent] called");return N({type:"dom.event",attributes:{dom_event_selector:t,dom_event_key_code:s,dom_event_type:e.type,dom_event_coordinates:n||{clientX:0,clientY:0},dom_event_target:{id:i.id,tagName:i.tagName,className:i.className,text:r}}})}queueEvent(e){try{this.logger.log("[dom-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}generateSelector(e,t={}){if(!e||!e.nodeType||e.nodeType!==Node.ELEMENT_NODE)return"";const n=t.root||document.body||document.documentElement,i=t.maxAttempts||10,s=t.priorityAttributes||["id","class","name","aria-label","type","title","alt"];if("html"===e.tagName?.toLowerCase())return"html";let r="",a=0,o=e;const l=[];for(;o&&o!==n&&o!==document.documentElement&&a<i;){let e=o.tagName?.toLowerCase()||"";try{const t=o.getAttribute("id");if(t&&/^[a-zA-Z][\w-]*$/.test(t))return`#${t}`;if(o.classList?.length){const t=Array.from(o.classList).filter((e=>e&&"string"==typeof e)).map((e=>`.${e}`));t.length&&(e+=t.join(""))}for(const t of s)if("id"!==t&&"class"!==t)try{const n=o.getAttribute(t);n&&(e+=`[${t}="${n.replace(/"/g,'\\"')}"]`)}catch(e){}}catch(t){e=o.tagName?.toLowerCase()||"*"}l.unshift(e||"*"),r=l.join(" > ");try{if(1===n.querySelectorAll(r).length)return r}catch(e){l.shift(),r=l.join(" > ")}try{o=o.parentElement}catch(e){break}a++}return r||"*"}},R=["log","info","warn","error","assert","trace"],_=class extends C{constructor(){super(...arguments),this.originalConsole=null,this.isInitialized=!1}initialize(){if(!this.isInitialized)try{this.originalConsole=this.captureConsoleMethods(),R.forEach((e=>{e in console&&(console[e]=(...t)=>{try{this.handleEvent(t,e)}catch(e){h(e)}finally{this.originalConsole?.[e]&&this.originalConsole[e](...t)}})})),this.isInitialized=!0}catch(e){h(e)}}destroy(){try{if(!this.isInitialized)return;R.forEach((e=>{this.originalConsole&&this.originalConsole[e]&&(console[e]=this.originalConsole[e])})),this.isInitialized=!1}catch(e){h(e)}}handleEvent(e,t){try{if(!I())return;const n=this.formatMessage(Array.isArray(e)?e:[e],t);if(!n||n?.includes("groundcoverIgnore"))return;const i=this.buildEvent({message:n,level:t});this.queueEvent(i)}catch(e){h(e)}}buildEvent({message:e,level:t}){return N({type:"log",attributes:{message:z({text:e}),level:t}})}queueEvent(e){try{this.logger.log("[logs-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}formatMessage(e,t){if(!Array.isArray(e))return String(e);try{return e.map((e=>{if(void 0===e)return"undefined";if(null===e)return"null";if("object"==typeof e){if(e instanceof Error)try{return"error"===t&&e.stack||e.toString()}catch{try{const t={name:e.name,message:e.message,stack:e.stack};return JSON.stringify(t)}catch{return Object.prototype.toString.call(e)}}try{return JSON.stringify(e)}catch{return Object.prototype.toString.call(e)}}return String(e)})).join(" ")}catch(e){return h(e),"[Error formatting console message]"}}captureConsoleMethods(){const e={};try{R.forEach((t=>{console&&"function"==typeof console[t]&&(e[t]=console[t].bind(console))}))}catch(e){h(e)}return e}};function k(e){try{if(null==e)return"";if("string"==typeof e)return e;if(e instanceof FormData)return"[form data]";if(e instanceof Blob)return"[blob data]";if(e instanceof ArrayBuffer)return"[arraybuffer data]";if("undefined"!=typeof Document){if(e instanceof Document)return"[document data]";const t=e;if(9===t?.nodeType)return"[document data]"}if(e instanceof URLSearchParams)try{return e.toString()}catch{return"[unreadable body]"}return Array.isArray(e)||"object"==typeof e?JSON.stringify(e):String(e)}catch(e){return h(`Failed to format body: ${e}`),"[unreadable body]"}}var x,P=class extends C{constructor(){super(...arguments),this.maxBodyLength=5e3,this.config=p.getInstance(),this.idGenerator=new f,this.handleEvent=e=>{try{if(this.shouldIgnoreRequest(e.url))return;if(!I())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){h(e)}},this.buildEvent=e=>{let t=e.url,n=e.url;this.logger.log("[network-events-listener.buildEvent] called",{event:e});try{t=new URL(e.url).pathname}catch(t){n=new URL(e.url,globalThis.location.href).href}this.logger.log("[network-events-listener.buildEvent] fullUrl",{fullUrl:n});const i=this.formatHeaders(e.request.headers),s=this.formatHeaders(e.response.headers),r=e.method?.toUpperCase()||"UNKNOWN",{traceId:a,spanId:o}=this.extractTraceIds(e.request.headers),l=z({text:e.request.body,maxLength:this.maxBodyLength}),d=z({text:e.response.body,maxLength:this.maxBodyLength}),c={type:"HTTP",operation:{name:r},resource_name:t,status:e.status?.toString(),subType:r,url:{full:n},http:{route:t,path:t,method:e.method,status:e.status?.toString(),request:{headers:i,method:e.method},response:{headers:s,status_code:e.status?.toString()}},error:e?.error?.type?{type:e.error?.type||"Unknown error"}:void 0,gc:{request:{body:l},response:{body:d}}},h={type:"network",timestamp:e?.timestamp&&!Number.isNaN(e.timestamp)?1e6*e.timestamp:void 0,end_timestamp:e?.end_time&&!Number.isNaN(e.end_time)?1e6*e.end_time:void 0,span_name:`${e.method} ${t}`,attributes:c};return a&&(h.traceId=a),o&&(h.spanId=o),N(h)}}async getResponseBody(e){let t;try{const n=e.clone().body;if(n){let e,i=n.getReader(),s=new TextDecoder,r="";for(;!(e=await i.read()).done;){let t=e.value;r+=s.decode(t)}t=r}else t=""}catch(e){t=`Unable to clone response: ${e}`}return t}initialize(){this.logger.log("[network-events-listener.initialize] called"),this.patchXHR(),this.patchFetch()}destroy(){globalThis.XMLHttpRequest.prototype.open=globalThis.XMLHttpRequest.prototype.open,globalThis.XMLHttpRequest.prototype.send=globalThis.XMLHttpRequest.prototype.send,globalThis.fetch=globalThis.fetch}shouldIgnoreRequest(e){try{const t=this.config.getConfig()?.getEndpoint();if(t&&e.includes(t))return!0;if([".tsx",".jsx",".css"].some((t=>e.toLowerCase().endsWith(t))))return!0;return(this.config.getConfig()?.options?.excludedUrls||[]).some((t=>{if(t instanceof RegExp)return t.test(e);if("string"==typeof t&&(t.includes("*")||t.includes("?"))){const n=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".");return new RegExp(n).test(e)}return e===t}))}catch(e){return h(e),!1}}queueEvent(e){try{this.logger.log("[network-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}patchXHR(){const e=this,t=globalThis.XMLHttpRequest.prototype.open,n=globalThis.XMLHttpRequest.prototype.send,i=globalThis.XMLHttpRequest.prototype.setRequestHeader;let s;globalThis.XMLHttpRequest.prototype.open=function(n,i,r=!0,a,o){if(s=Date.now(),e.shouldIgnoreRequest(i.toString()))return t.apply(this,[n,i,r,a,o]);const l=new URL(i.toString(),globalThis.location.href).href;return this._requestMethod=n,this._requestUrl=l,this._requestHeaders={},t.apply(this,[n,i,r,a,o])},globalThis.XMLHttpRequest.prototype.setRequestHeader=function(e,t){return this._requestHeaders&&(this._requestHeaders[e]=t),i.apply(this,[e,t])},globalThis.XMLHttpRequest.prototype.send=function(...t){const i=this._requestUrl?.toString();if(!i||e.shouldIgnoreRequest(i))return n.apply(this,t);if(e.shouldAddTraceHeader(i)){const t=e.config.getConfig(),n=e.getTraceIds();t?.options?.traceOrigin?.name&&e.addHeaderToXhrRequest({request:this,headerName:t.options.traceOrigin.name,headerValue:t.options.traceOrigin.value}),n&&(t?.options?.tracePropagationTraceIdHeaderName&&e.addHeaderToXhrRequest({request:this,headerName:t.options.tracePropagationTraceIdHeaderName,headerValue:n.decimalTraceId}),t?.options?.tracePropagationSpanIdHeaderName&&e.addHeaderToXhrRequest({request:this,headerName:t.options.tracePropagationSpanIdHeaderName,headerValue:n.decimalSpanId}),Boolean(t?.options?.tracePropagationHeaders)&&t?.options?.tracePropagationHeaders?.forEach((t=>{e.addHeaderToXhrRequest({request:this,headerName:t,headerValue:n.traceparent})})),t?.options?.tracePropagationHeaders?.length||e.addHeaderToXhrRequest({request:this,headerName:"traceparent",headerValue:n.traceparent}))}return this._requestBody=t[0]||"",this.addEventListener("load",(()=>{const t=Date.now(),n={};this.getAllResponseHeaders().split(/\r?\n/).forEach((e=>{const[t,i]=e.split(": ");t&&i&&(n[t.trim()]=i.trim())}));const i=k(this._requestBody),r=k(""===this.responseType||"text"===this.responseType?this.responseText:this.response),a={timestamp:s,end_time:t,method:this._requestMethod,url:this._requestUrl,body:i,status:this.status,request:{headers:this._requestHeaders||{},body:i},response:{headers:n,body:r}};e.handleEvent(a)})),n.apply(this,t)}}normalizeHeaders(e,t){try{const n=e?new Headers(e):new Headers;return t?(t instanceof Headers?t.forEach(((e,t)=>n.set(t,e))):Array.isArray(t)?new Headers(t).forEach(((e,t)=>n.set(t,e))):"object"==typeof t&&Object.entries(t).forEach((([e,t])=>n.set(e,t))),n):n}catch{return new Headers}}addTraceHeaders(e){const t=this.config.getConfig(),n=this.getTraceIds();if(t?.options?.traceOrigin?.name&&this.addHeaderToFetchRequest({init:e,headerName:t.options.traceOrigin.name,headerValue:t.options.traceOrigin.value}),!n)return;t?.options?.tracePropagationTraceIdHeaderName&&this.addHeaderToFetchRequest({init:e,headerName:t.options.tracePropagationTraceIdHeaderName,headerValue:n.decimalTraceId}),t?.options?.tracePropagationSpanIdHeaderName&&this.addHeaderToFetchRequest({init:e,headerName:t.options.tracePropagationSpanIdHeaderName,headerValue:n.decimalSpanId});const i=t?.options?.tracePropagationHeaders;(i?.length?i:["traceparent"]).forEach((t=>{this.addHeaderToFetchRequest({init:e,headerName:t,headerValue:n.traceparent})}))}extractHeadersRecord(e){const t={};return e instanceof Headers&&e.forEach(((e,n)=>{t[n]=e})),t}patchFetch(){const e=globalThis.fetch;globalThis.fetch=(...t)=>{const n=Date.now();let[i,s]=t;s={...s||{}},t[1]=s;const r=i instanceof Request,a=s?.method||"GET",o=s?.body||"",l=i instanceof Request?i.url:i.toString();if(this.shouldIgnoreRequest(l))return e.apply(globalThis,t);const d=this.shouldAddTraceHeader(l);s||(t[1]={},s=t[1]),s.headers=this.normalizeHeaders(r?i.headers:void 0,s.headers),d&&this.addTraceHeaders(s);const c=this.extractHeadersRecord(s.headers),h=k(o);return e.apply(globalThis,t).then((e=>{const t=Date.now(),i=e.clone(),s={};i.headers.forEach(((e,t)=>{s[t]=e}));const r={method:a,url:l,timestamp:n,body:h,status:i.status,end_time:t,request:{headers:c,body:h},response:{headers:s,body:""}};try{s["content-type"]?.includes("text/event-stream")?(r.response.body="[unreadable response body]",this.handleEvent(r)):this.getResponseBody(i).then((e=>{r.response.body=e,this.handleEvent(r)})).catch((e=>{r.response.body="[unreadable response body]",this.handleEvent(r),this.logger.log("[network-events-listener.patchFetch] error",{error:e})}))}catch(e){r.response.body="[unreadable response body]",this.handleEvent(r),this.logger.log("[network-events-listener.patchFetch] error",{error:e})}return e})).catch((e=>{const t=Date.now();let n="NetworkError";const i=e.message||"Unknown network error";e instanceof TypeError&&i.includes("Failed to fetch")?n="ERR_NETWORK_FAILURE":i.includes("Name not resolved")?n="ERR_NAME_NOT_RESOLVED":i.includes("Connection refused")&&(n="ERR_CONNECTION_REFUSED");const s={method:a,url:l,body:h,status:0,end_time:t,request:{headers:c,body:h},response:{headers:{},body:""},error:{type:n}};throw this.handleEvent(s),e}))}}formatHeaders(e){const t=["authorization","cookie","set-cookie"];return Object.entries(e)?.reduce(((e,[n,i])=>{const s=n.toLowerCase();return t.includes(s)||/(token|key|secret|password)/i.test(s)?e[n]="[REDACTED]":e[n]=z({text:i}),e}),{})}extractTraceIds(e){const t=this.config.getConfig();let n="",i="";if(t?.options?.tracePropagationTraceIdHeaderName){const i=e[t.options.tracePropagationTraceIdHeaderName];i&&"string"==typeof i&&(n=i)}if(t?.options?.tracePropagationSpanIdHeaderName){const n=e[t.options.tracePropagationSpanIdHeaderName];n&&"string"==typeof n&&(i=n)}if(!n||!i){const t=this.extractTraceparentHeader(e);if(t){const e=t.split("-");4===e.length&&"00"===e[0]&&(!n&&e[1]&&32===e[1].length&&(n=e[1]),!i&&e[2]&&16===e[2].length&&(i=e[2]))}}return{traceId:n,spanId:i}}extractTraceparentHeader(e){const t=this.config.getConfig();if(t?.options?.tracePropagationHeaders?.length)for(const n of t.options.tracePropagationHeaders){const t=e[n];if(t&&"string"==typeof t)return t}const n=e.traceparent;return n&&"string"==typeof n?n:""}getTraceIds(){const e=this.idGenerator.generateSpanId(),t=this.idGenerator.generateTraceId();let n,i;try{n=BigInt("0x"+t).toString(10),i=BigInt("0x"+e).toString(10)}catch(s){this.logger.log("[network-events-listener.getTraceIds] error",{error:s}),n=t,i=e}return{traceparent:`00-${t}-${e}-01`,traceId:t,spanId:e,decimalTraceId:n,decimalSpanId:i}}addHeaderToXhrRequest({request:e,headerName:t,headerValue:n}){if(this.logger.log("[network-events-listener.addHeaderToXhrRequest] called",{request:e,headerName:t,headerValue:n}),this.isValidHeaderName(t))try{e.setRequestHeader(t,n),e._requestHeaders[t]=n}catch(e){this.logger.log("[network-events-listener.addHeaderToXhrRequest] Error setting header",{error:e,headerName:t,headerValue:n})}else this.logger.log("[network-events-listener.addHeaderToXhrRequest] Invalid header name",{headerName:t})}addHeaderToFetchRequest({init:e,headerName:t,headerValue:n}){if(this.logger.log("[network-events-listener.addHeaderToFetchRequest] called",{init:e,headerName:t,headerValue:n}),this.isValidHeaderName(t))try{e.headers instanceof Headers?e.headers.set(t,n):e.headers={...e.headers,[t]:n}}catch(e){this.logger.log("[network-events-listener.addHeaderToFetchRequest] Error setting header",{error:e,headerName:t,headerValue:n})}else this.logger.log("[network-events-listener.addHeaderToFetchRequest] Invalid header name",{headerName:t})}isValidHeaderName(e){if(!e||"string"!=typeof e)return!1;return/^[a-zA-Z0-9!#$&'*+\-.^_`|~]+$/.test(e)}shouldAddTraceHeader(e){const t=this.config.getConfig();if(this.logger.log("[network-events-listener.shouldAddTraceHeader] called",{url:e,config:t}),!t?.options?.tracePropagationUrls?.length)return!1;const n=t.options.tracePropagationUrls?.some((t=>{const n=t.replace(/\*/g,".*"),i=new RegExp(`^${n}$`),s=e.startsWith("/")?new URL(e,globalThis.location.href).pathname:e;return i.test(s)}));return this.logger.log("[network-events-listener.shouldAddTraceHeader] result",{url:e,result:n}),n}},A=class extends C{constructor(){super(...arguments),this.handleEvent=(e,t)=>{this.logger.log("[errors-events-listener.handleEvent] called");try{let n;if(e instanceof Error)n=e,this.enhanceError(n);else if(e instanceof ErrorEvent){if(n=e.error||new Error(e.message||"Unknown error"),/Script error\.?/.test(n.message))return;this.enhanceError(n,e)}else{if(!(e instanceof PromiseRejectionEvent))return;n=this.createUnhandledRejectionError(e)}const i=this.buildEvent(n,t);this.queueEvent(i)}catch(e){h(e)}}}initialize(){m?.addEventListener("error",this.handleEvent),m?.addEventListener("unhandledrejection",this.handleEvent)}destroy(){m?.removeEventListener("error",this.handleEvent),m?.removeEventListener("unhandledrejection",this.handleEvent)}buildEvent(e,t){return N({type:"exception",attributes:{error_type:e.name||"Error",error_message:e.message||"Unknown error",error_stacktrace:this.buildStackTrace(e),error_fingerprint:`${e.name}:${z({text:e.message,maxLength:400})}`,error_handled:t?.handled||!1}})}queueEvent(e){try{this.logger.log("[errors-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}enhanceError(e,t){const{filename:n,lineno:i,colno:s}=t||{};n&&!e.fileName&&Object.defineProperty(e,"fileName",{value:n}),i&&!e.lineNumber&&Object.defineProperty(e,"lineNumber",{value:i}),s&&!e.columnNumber&&Object.defineProperty(e,"columnNumber",{value:s})}createUnhandledRejectionError(e){let t;if(e.reason instanceof Error)t=e.reason;else{const n="object"==typeof e.reason?JSON.stringify(e.reason,null,2):String(e.reason);t=new Error(n),t.name="UnhandledRejection",Object.defineProperty(t,"originalReason",{value:e.reason,enumerable:!1})}return t}buildStackTrace(e){if(!e)return[];try{return n.parse(e).map((e=>({filename:e.fileName||"unknown",function:e.functionName||"anonymous",lineno:e.lineNumber||0,colno:e.columnNumber||0})))}catch(e){return[]}}},M=class extends C{constructor({isEnabled:e}){if(super(),this.currentUrl="",this.originalPushState=null,this.originalReplaceState=null,this.isInitialized=!1,this.isAutomaticNavigationEnabled=!1,this.activeNavigation=null,this.popStateHandler=()=>{this.handleLocationChange()},this.hashChangeHandler=()=>{this.handleLocationChange()},this.isInBrowserEnvironment()&&e)try{this.isAutomaticNavigationEnabled=e,this.currentUrl=m.location.href,this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState}catch(e){h(e)}}isInBrowserEnvironment(){try{return void 0!==m&&void 0!==m.location&&void 0!==m.history&&"function"==typeof m.addEventListener}catch(e){return h(e),!1}}initialize(){try{if(this.logger.log("[navigation-listener.initialize] called"),!this.isInBrowserEnvironment()||!this.originalPushState||!this.originalReplaceState)return void this.logger.log("[navigation-listener.initialize] Browser environment not available, skipping initialization");if(!this.isAutomaticNavigationEnabled)return void this.logger.log("[navigation-listener.initialize] Automatic navigation is disabled, skipping initialization");const e=this.originalPushState,t=this.originalReplaceState;history.pushState=(...t)=>{const n=e.apply(history,t);return this.handleLocationChange(),n},history.replaceState=(...e)=>{const n=t.apply(history,e);return this.handleLocationChange(),n},m&&"function"==typeof m.addEventListener&&(m.addEventListener("popstate",this.popStateHandler),m.addEventListener("hashchange",this.hashChangeHandler)),this.isInitialized=!0}catch(e){h(e)}}destroy(){try{this.logger.log("[navigation-listener.destroy] called"),this.isInitialized&&this.originalPushState&&this.originalReplaceState&&(history.pushState=this.originalPushState,history.replaceState=this.originalReplaceState),m&&"function"==typeof m.removeEventListener&&(m.removeEventListener("popstate",this.popStateHandler),m.removeEventListener("hashchange",this.hashChangeHandler)),this.isInitialized=!1}catch(e){h(e)}}handleEvent(){try{this.logger.log("[navigation-listener.handleEvent] called");const e=this.buildEvent();this.queueEvent(e)}catch(e){h(e)}}buildEvent(){this.logger.log("[navigation-listener.buildEvent] called",m.location.href);return N({type:"navigation",attributes:{page_url:m.location.href,metadata:this.activeNavigation?.metadata,duration_ms:this.activeNavigation?.duration_ms||0,start_timestamp:this.activeNavigation?.startTime||0,end_timestamp:this.activeNavigation?.endTime||0}})}queueEvent(e){try{this.logger.log("[navigation-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}startNavigation(e){this.logger.log("[navigation-listener.startNavigation] called",e),this.activeNavigation={page_url:m.location.href,metadata:e,startTime:Date.now(),endTime:0,duration_ms:0}}endNavigation(e){this.logger.log("[navigation-listener.endNavigation] called",e),this.activeNavigation?(this.logger.log("[navigation-listener.endNavigation] active navigation",this.activeNavigation),this.activeNavigation.endTime=Date.now(),this.activeNavigation.duration_ms=this.activeNavigation.endTime-this.activeNavigation.startTime,this.handleEvent()):this.logger.log("[navigation-listener.endNavigation] no active navigation found")}handleLocationChange(){try{if(!this.isInitialized)return;if(this.logger.log("[navigation-listener.handleLocationChange] called"),this.currentUrl===m.location.href)return;let e,t;try{e=new URL(m.location.href),t=new URL(this.currentUrl)}catch(e){return void h(e)}const n=e=>e.startsWith("#/"),i=n(e.hash)||n(t.hash);(e.pathname!==t.pathname||i&&e.hash!==t.hash)&&(this.currentUrl=m.location.href,this.handleEvent())}catch(e){h(e)}}},D=class extends C{constructor(){super(),this.loadEventHandler=()=>{this.logger.log("load event"),this.handleEvent()}}initialize(){try{this.logger.log("[page-load-listener.initialize] called"),this.logger.log("globalThis",m),"complete"===m?.document?.readyState?(this.logger.log("Page already loaded, triggering event immediately"),this.handleEvent()):m?.addEventListener("load",this.loadEventHandler)}catch(e){this.logger.log("[page-load-listener.initialize] error",e),h(e)}}destroy(){m?.removeEventListener("load",this.loadEventHandler)}handleEvent(){try{this.logger.log("[page-load-listener.handleEvent] called");const e=this.buildEvent();this.queueEvent(e)}catch(e){h(e)}}buildEvent(){const e=performance.getEntriesByType("navigation")[0],t=e?e.loadEventEnd-e.startTime:0,n=performance.getEntriesByType("resource"),i={count:n.length,totalSize:0,totalDuration:0,byType:{}};n.forEach((e=>{const t=e,n=t.transferSize||0,s=t.duration,r=t.initiatorType;i.totalSize+=n,i.totalDuration+=s,i.byType[r]||(i.byType[r]={count:0,size:0,duration:0}),i.byType[r].count++,i.byType[r].size+=n,i.byType[r].duration+=s}));return N({type:"pageload",attributes:{page_url:m?.location?.href||"",page_load_time:t,page_referrer:m?.document?.referrer||"",page_resources:i}})}queueEvent(e){try{this.logger.log("[page-load-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}},U=class extends C{constructor(){super(...arguments),this.handleEvent=e=>{try{if(!I())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){h(e)}}}initialize(){i(this.handleEvent),s(this.handleEvent),r(this.handleEvent),a(this.handleEvent),o(this.handleEvent)}destroy(){}buildEvent(e){return N({type:"performance",attributes:{performance_metric_name:e.name,performance_metric_value:e.value,performance_metric_id:e.id,performance_metric_navigation_type:e.navigationType||""}})}queueEvent(e){try{this.logger.log("[performance-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}},O=class{constructor(){this.logger=d.getInstance(),this.eventsPool=L.getInstance(),this.configManager=p.getInstance(),this.logEventsListener=null,this.domEventsListener=null,this.errorsEventsListener=null,this.networkEventsListener=null,this.navigationListener=null,this.performanceListener=null,this.pageLoadListener=null}instrument(){this.logger.log("[instrumentation-manager.instrument] called");const e=this.configManager.getConfig(),t=e?.options?.enabledEvents,n=!t||0===t.length,i=[];(n||t?.includes("pageload"))&&(this.pageLoadListener=new D,this.pageLoadListener.initialize(),i.push("pageload")),(n||t?.includes("dom"))&&(this.domEventsListener=new q,this.domEventsListener.initialize(),i.push("dom")),(n||t?.includes("logs"))&&(this.logEventsListener=new _,this.logEventsListener.initialize(),i.push("logs")),(n||t?.includes("exceptions"))&&(this.errorsEventsListener=new A,this.errorsEventsListener.initialize(),i.push("exceptions")),(n||t?.includes("network"))&&(this.networkEventsListener=new P,this.networkEventsListener.initialize(),i.push("network")),(n||t?.includes("performance"))&&(this.performanceListener=new U,this.performanceListener.initialize(),i.push("performance")),this.navigationListener=new M({isEnabled:n||t?.includes("navigation")}),this.navigationListener.initialize(),i.push("navigation"),this.logger.log("[instrumentation-manager.instrument] initialized listeners based on config:",i)}sendCustomEvent(e){this.logger.log("[instrumentation-manager.sendCustomEvent] called",e);try{const t=N({type:"custom",attributes:{custom_event_name:e?.event,custom_event_attributes:e?.attributes}});this.eventsPool.addEvent(t)}catch(e){h(e)}}captureException(e){try{this.logger.log("[instrumentation-manager.captureException] called",e),this.errorsEventsListener?.handleEvent(e,{handled:!0})}catch(e){h(e)}}isNavigationTrackingEnabled(){const e=this.configManager.getConfig();return e?.options?.enabledEvents?.includes("navigation")||0===e?.options?.enabledEvents?.length}startNavigation(e){this.logger.log("[instrumentation-manager.startNavigation] called",e),this.isNavigationTrackingEnabled()?this.logger.log("[instrumentation-manager.startNavigation] startNavigation called while navigation tracking is enabled. Ignoring. If you wish to track navigations manually, please disable navigation tracking via the enabledEvents array in the config."):this.navigationListener?.startNavigation(e)}endNavigation(e){this.logger.log("[instrumentation-manager.endNavigation] called",e),this.isNavigationTrackingEnabled()?this.logger.log("[instrumentation-manager.endNavigation] endNavigation called while navigation tracking is enabled. Ignoring. If you wish to track navigations manually, please disable navigation tracking via the enabledEvents array in the config."):this.navigationListener?.endNavigation(e)}uninstrument(){this.domEventsListener?.destroy(),this.logEventsListener?.destroy(),this.errorsEventsListener?.destroy(),this.networkEventsListener?.destroy(),this.navigationListener?.destroy(),this.performanceListener?.destroy(),this.pageLoadListener?.destroy()}},j="gcSample",F=class{constructor(e){this.initialized=!1,this.logger=d.initialize({debug:e.options?.debug||!1,prefix:"[groundcover]"}),this.logger.log("[session-manager] initialize called"),this.instrumentationManager=new O,this.idGenerator=new f;if(!this.getSamplingDecision(e.options?.sessionSampleRate))return void this.logger.log("[session-manager] session is not sampled");if(this.initialized)return void this.logger.log("[session-manager] SDK already initialized");const t=p.getInstance();t.initialize(e);L.getInstance().initialize();const n=e.sessionId,i=t.getSessionId();n?(t.setSessionId(n),this.logger.log("[session-manager] using provided sessionId:",n)):i||t.setSessionId(this.idGenerator.generateId()),this.instrumentationManager.instrument(),this.initialized=!0}getSamplingDecision(e){try{if(!e||1===e)return!0;const t=globalThis.sessionStorage?.getItem(j);if(t){const e="1"===t;return this.logger.log("[session-manager] using stored sampling decision:",e),e}const n=!e||Math.random()<e;return globalThis?.sessionStorage?.setItem(j,n?"1":"0"),this.logger.log("[session-manager] stored new sampling decision:",n),n}catch(t){this.logger.log("[session-manager] session storage access failed:",t);const n=!e||Math.random()<e;return this.logger.log("[session-manager] using fallback sampling decision:",n),n}}identifyUser(e){if(this.logger.log("[session-manager] identifyUser called"),!this.initialized)return void this.logger.log("[session-manager] cannot identify user: SDK not initialized");p.getInstance().updateConfig({userIdentifier:e})}updateConfig(e){if(!this.initialized)return void this.logger.log("[session-manager] cannot update config: SDK not initialized");p.getInstance().updateConfig(e)}sendCustomEvent(e){this.initialized?this.instrumentationManager.sendCustomEvent(e):this.logger.log("[session-manager] cannot send custom event: SDK not initialized")}startNavigation(e){this.initialized?this.instrumentationManager.startNavigation(e):this.logger.log("[session-manager] cannot start navigation: SDK not initialized")}endNavigation(e){this.initialized?this.instrumentationManager.endNavigation(e):this.logger.log("[session-manager] cannot end navigation: SDK not initialized")}captureException(e){this.initialized?this.instrumentationManager.captureException(e):this.logger.log("[session-manager] Cannot capture exception: SDK not initialized")}async setSessionId(e){if(this.logger.log("[session-manager] setSessionId called"),this.initialized)try{const t=L.getInstance();await t.flushSync();const n=e||this.idGenerator.generateId();p.getInstance().setSessionId(n),this.logger.log("[session-manager] session ID set successfully:",n)}catch(e){this.logger.log("[session-manager] failed to set session ID:",e)}else this.logger.log("[session-manager] cannot set session ID: SDK not initialized")}destroy(){this.initialized&&(this.instrumentationManager.uninstrument(),globalThis.sessionStorage?.removeItem("gcId"),this.initialized=!1)}};var $={init:function(e){try{x=new F({cluster:e?.cluster||"",environment:e?.environment||"",namespace:e?.namespace,dsn:e?.dsn||"",appId:e?.appId||"",userIdentifier:e?.userIdentifier,apiKey:e?.apiKey||"",options:e?.options,sessionId:e?.sessionId})}catch(e){h(e)}},identifyUser:function(e){x?x.identifyUser(e):console.warn("[groundcover] identifyUser: groundcover is not initialized. please call init() first")},sendCustomEvent:function(e){x&&x.sendCustomEvent(e)},captureException:function(e){x&&x.captureException(e)},updateConfig:function(e){x&&x.updateConfig(e)},startNavigation:function(e){x?x.startNavigation(e):console.warn("[groundcover] startNavigation: groundcover is not initialized. please call init() first")},endNavigation:function(e){x?x.endNavigation(e):console.warn("[groundcover] endNavigation: groundcover is not initialized. please call init() first")},setSessionId:async function(e){if(x)try{await x.setSessionId(e)}catch(e){console.error("[groundcover] setSessionId: failed to set session ID:",e)}else console.warn("[groundcover] setSessionId: groundcover is not initialized. please call init() first")}};if("undefined"!=typeof window&&!window.groundcover)try{window.groundcover=$}catch(e){console.warn("[groundcover] Failed to expose groundcover on window:",e)}var X=$;export{X as default};
1
+ import{strToU8 as e,gzipSync as t}from"fflate";import n from"error-stack-parser";import{onCLS as i,onLCP as s,onFCP as r,onTTFB as a,onINP as o}from"web-vitals";import{record as l}from"rrweb";var d=console.log.bind(console),c=class e{constructor(){this.isDebugEnabled=!1,this.prefix=""}static initialize(t){return e.instance||(e.instance=new e),t&&(e.instance.isDebugEnabled=t.debug??!1,e.instance.prefix=t.prefix??""),e.instance}static getInstance(t){return e?.instance||e.initialize(t)}formatMessage(e){return`[${(new Date).toISOString()}] ${this.prefix} ${e}`}log(e,...t){this.isDebugEnabled&&d(this.formatMessage(e),...t)}updateConfig(e){this.isDebugEnabled=e.debug??this.isDebugEnabled,this.prefix=e.prefix??this.prefix}},g=c.getInstance();function h(e){g.log("[error-handler.handleError] called",e,{groundcoverIgnore:!0})}var u={batchSize:10,batchTimeout:1e4,eventSampleRate:1,sessionSampleRate:1,environment:"development",debug:!1,enableCompression:!0,maskFields:[],enableMasking:!1,enabledEvents:[],tracePropagationUrls:[],tracePropagationHeaders:[],tracePropagationTraceIdHeaderName:"",tracePropagationSpanIdHeaderName:"",traceOrigin:{name:"",value:""}},p=class{constructor(e){this.dsn=e?.dsn||"",this.appId=e?.appId||"",this.cluster=e?.cluster||"",this.apiKey=e?.apiKey||"",this.environment=e?.environment||"",this.namespace=e?.namespace||"",this.userIdentifier=e?.userIdentifier||null,this.options={...u,...e?.options||{}}}getEndpoint(){return this.dsn?.startsWith("http")?this.dsn:`https://${this.dsn}`}updateConfig(e){e.options&&(this.options={...this.options,...e.options}),e.userIdentifier&&(this.userIdentifier={...this.userIdentifier,...e.userIdentifier}),e.appId&&(this.appId=e.appId),e.dsn&&(this.dsn=e.dsn),e.apiKey&&(this.apiKey=e.apiKey),e.cluster&&(this.cluster=e.cluster),e.environment&&(this.environment=e.environment),e.namespace&&(this.namespace=e.namespace)}},m=class e{constructor(){this.config=null,this.logger=c.getInstance(),this.sessionId=null}static getInstance(){return e.instance||(e.instance=new e),e.instance}initialize(e){this.config||(this.config=new p(e))}getConfig(){return this.config?this.config:(this.logger.log("[config-manager] configuration not initialized"),null)}getSessionId(){if(this.sessionId)return this.sessionId;const e=globalThis?.sessionStorage?.getItem("gcId");return e||""}setSessionId(e){this.sessionId=e,globalThis?.sessionStorage?.setItem("gcId",e)}updateConfig(e){this.logger.log("[config-manager] updateConfig called"),this.config?(e&&(this.logger.log("[config-manager] updating options"),this.config.updateConfig(e)),e?.userIdentifier&&(this.logger.log("[config-manager] updating user identifier"),this.config.userIdentifier={...this.config.userIdentifier,...e.userIdentifier})):this.logger.log("[config-manager] configuration not initialized")}},f="object"==typeof globalThis?globalThis:"object"==typeof self?self:"object"==typeof window?window:"object"==typeof global?global:{},v=class{constructor(){this.generateTraceId=E(16),this.generateSpanId=E(8),this.generateId=E(16)}},y=Array(32);function E(e){return function(){for(let t=0;t<2*e;t++)y[t]=Math.floor(16*Math.random())+48,y[t]>=58&&(y[t]+=39);return String.fromCharCode.apply(null,y.slice(0,2*e))}}var b=m.getInstance(),I=new v,w=c.getInstance();function S(){const e=b?.getConfig()?.options?.eventSampleRate;return!(void 0!==e&&!Number.isNaN(e))||Math.random()<=e}function N(e,t="",n=new WeakSet){if(n.has(e))return{[t||"circular_reference"]:"[Circular]"};n.add(e);try{return Object.entries(e).reduce(((e,[i,s])=>{const r=t?`${t}.${i}`:i;return"object"==typeof s&&null!==s?Array.isArray(s)?e[r]=s.map(((e,t)=>"object"==typeof e&&null!==e?N(e,`${r}[${t}]`,n):e)):Object.assign(e,N(s,r,n)):e[r]=s,e}),{})}catch(e){return w.log("[events-processors.formatEventObject] Error formatting event object",e),{[t||"format_error"]:"[Error formatting object]"}}finally{n.delete(e)}}function T(e){const t=1e6*Date.now(),n=I.generateId(),i=e.spanId||I.generateSpanId(),s=e.traceId||I.generateTraceId(),r=e.parentSpanId||"",a=N(e.attributes||{}),o=function(){const e=f?.location;return e?{path:e.hash&&!e.hash.match(/^#[a-z0-9-]+$/i)&&e.hash.startsWith("#/")?e.hash:e.pathname,url:e.href,title:f?.document?.title||""}:{path:"",url:"",title:f?.document?.title||""}}(),l={type:e.type,id:n,spanId:i,parentSpanId:r,traceId:s,attributes:{...a,location:o}};return e.span_name&&(l.span_name=e.span_name),"network"===e.type?(l.start_timestamp=e.timestamp||t,l.end_timestamp=e?.end_timestamp):l.timestamp=t,l}var R=class{constructor(){this.logger=c.getInstance(),this.config=m.getInstance()}compress(n){const i=this.config.getConfig();if(!i?.options?.enableCompression)return{data:(new TextEncoder).encode(n),isCompressed:!1};try{const i=e(n);return{data:t(i),isCompressed:!0}}catch(e){return{data:(new TextEncoder).encode(n),isCompressed:!1}}}async send(e){const t=this.config.getConfig();if(t)try{t?.options?.debug&&this.logger.log("Sending batch:",e,{groundcoverIgnore:!0});const n=t.apiKey,i=this.buildEndpoint();if(!n)return void this.logger.log("No API key found");const s=JSON.stringify(e),{data:r,isCompressed:a}=this.compress(s);fetch(i,{method:"POST",headers:{"Content-Type":"application/json",apikey:n,"Content-Encoding":a?"gzip":""},body:r}).catch((e=>{this.logger.log("Network error while sending batch:",e,{groundcoverIgnore:!0})}))}catch(e){t.options.debug&&this.logger.log("Failed to send batch:",e,{groundcoverIgnore:!0})}}buildEndpoint(){const e=this.config.getConfig();if(!e)return"";const{dsn:t}=e;return`${t}/json/rum`}},L=["navigation","dom.event"],z=class e{constructor(){this.events=[],this.timeoutId=null,this.config=m.getInstance(),this.logger=c.getInstance(),this.initialized=!1,this.transporter=new R}static getInstance(){return e.instance||(e.instance=new e),e.instance}initialize(){try{if(this.initialized)return;this.scheduleFlush(),globalThis.addEventListener("unload",(()=>{this.flush()})),this.initialized=!0}catch(e){h(e)}}addEvent(e){if(e&&this.initialized)try{const t=this.config.getConfig()?.options?.beforeSend,n=this.config.getConfig()?.options?.enrichEvent;if(t&&!t(e))return;n&&(e=n(e)),this.events.push(e);const i=this.config.getConfig()?.options?.batchSize||100;this.events.length>=i&&!L.includes(e.type)&&this.flush()}catch(e){h(e)}}flush(){try{if(!this.events?.length||!this.initialized)return;if(!this.config.getConfig()?.cluster)return void this.logger.log("[events-pool.flush] skipping flush: no cluster");this.transporter.send({sessionAttributes:this.getSessionAttributes(),events:this.events}),this.events=[],this.scheduleFlush()}catch(e){h(e)}}async flushSync(){try{if(!this.events?.length||!this.initialized)return;if(!this.config.getConfig()?.cluster)return void this.logger.log("[events-pool.flush] skipping flush: no cluster");await this.transporter.send({sessionAttributes:this.getSessionAttributes(),events:this.events}),this.events=[]}catch(e){h(e)}}scheduleFlush(){try{null!==this.timeoutId&&(f.clearTimeout(this.timeoutId),this.timeoutId=null);const e=this.config.getConfig()?.options?.batchTimeout;if(!e)return;this.timeoutId=f.setTimeout((()=>{this.timeoutId=null,this.flush()}),e)}catch(e){h(e)}}detectBrowser(){const e=navigator.userAgent;let t="unknown",n="unknown";const i=navigator.platform||"unknown",s=/Mobile|Android|iPhone|iPad|iPod/i.test(e);return/Edg/.test(e)?(t="Edge",n=e.match(/Edg\/([\d.]+)/)?.[1]||n):/Chrome/.test(e)&&!/Chromium/.test(e)?(t="Chrome",n=e.match(/Chrome\/([\d.]+)/)?.[1]||n):/Firefox/.test(e)?(t="Firefox",n=e.match(/Firefox\/([\d.]+)/)?.[1]||n):/Safari/.test(e)&&!/Chrome/.test(e)?(t="Safari",n=e.match(/Version\/([\d.]+)/)?.[1]||n):/Trident/.test(e)?(t="Internet Explorer",n=/rv:([^)]+)\)/i.test(e)?e.match(/rv:([^)]+)\)/i)?.[1]||n:e.match(/MSIE ([^;]+)/)?.[1]||n):/OPR/.test(e)&&(t="Opera",n=e.match(/OPR\/([\d.]+)/)?.[1]||n),{name:t,version:n,platform:i,language:navigator.language,mobile:s}}getSessionAttributes(){const e=this.detectBrowser();return{cluster:this.config.getConfig()?.cluster||"",env:this.config.getConfig()?.environment||"",namespace:this.config.getConfig()?.namespace||"",session_id:this.config.getSessionId(),user:this.config.getConfig()?.userIdentifier||{},"service.name":this.config.getConfig()?.appId,userAgent:navigator.userAgent,browser:e}}};z.instance=null;var C=z,H=class{constructor(){this.logger=c.getInstance(),this.eventsPool=C.getInstance()}};function q({text:e,maxLength:t=1e4}){return e?e.length<=t||"string"!=typeof e?e:e.substring(0,t):""}var _=class extends H{constructor(){super(...arguments),this.eventHandlers=[],this.capturedEvents=["click","change","keydown","select","submit"],this.config=m.getInstance(),this.getShouldMaskText=e=>{const t=this.config.getConfig(),n=t?.options?.maskFields||[],i=t?.options?.enableMasking||!1;return(["password"===e.target?.type,e.target?.id?.toLowerCase().includes("password"),e.target?.id?.toLowerCase().includes("credit-card"),e.target?.id?.toLowerCase().includes("cc"),e.target?.className?.toLowerCase().includes("cc"),e.target?.className?.toLowerCase().includes("credit-card"),e.target?.className?.toLowerCase().includes("credit-card"),e.target?.hasAttribute("data-private")].some((e=>e))||n.some((t=>e.target?.id?.toLowerCase().includes(t))))&&i},this.getKeyCode=e=>{if(e instanceof KeyboardEvent&&e.code&&"Dead"!==e.key){const t=this.getShouldMaskText({target:e.target});return t||t?"*":e.key}return""},this.getText=e=>{const t=e.target,n=this.config.getConfig();return n?.options?.enableMasking||!1?"*":q({text:t.innerText||""})},this.getSelector=e=>e.target instanceof Element&&this.generateSelector(e.target)||"",this.getCoordinates=e=>{if({mouseup:!0,mousedown:!0,mousemove:!0,mouseover:!0}[e.type]){const{clientX:t,clientY:n}=e||{};return{clientX:t,clientY:n}}return null}}initialize(){try{this.logger.log("[dom-events-listener.initialize] called"),this.capturedEvents?.forEach((e=>{const t=e=>{try{this.handleEvent(e)}catch(e){h(e)}};this.eventHandlers.push({type:e,handler:t}),f?.addEventListener(e,t)}))}catch(e){h(e)}}destroy(){this.eventHandlers.forEach((({type:e,handler:t})=>{global?.removeEventListener?.(e,t)})),this.eventHandlers=[]}handleEvent(e){try{if(!S())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){h(e)}}buildEvent(e){const t=this.getSelector(e),n=this.getCoordinates(e),i=e.target,s=this.getKeyCode(e),r=this.getText(e);this.logger.log("[dom-events-listener.buildEvent] called");return T({type:"dom.event",attributes:{dom_event_selector:t,dom_event_key_code:s,dom_event_type:e.type,dom_event_coordinates:n||{clientX:0,clientY:0},dom_event_target:{id:i.id,tagName:i.tagName,className:i.className,text:r}}})}queueEvent(e){try{this.logger.log("[dom-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}generateSelector(e,t={}){if(!e||!e.nodeType||e.nodeType!==Node.ELEMENT_NODE)return"";const n=t.root||document.body||document.documentElement,i=t.maxAttempts||10,s=t.priorityAttributes||["id","class","name","aria-label","type","title","alt"];if("html"===e.tagName?.toLowerCase())return"html";let r="",a=0,o=e;const l=[];for(;o&&o!==n&&o!==document.documentElement&&a<i;){let e=o.tagName?.toLowerCase()||"";try{const t=o.getAttribute("id");if(t&&/^[a-zA-Z][\w-]*$/.test(t))return`#${t}`;if(o.classList?.length){const t=Array.from(o.classList).filter((e=>e&&"string"==typeof e)).map((e=>`.${e}`));t.length&&(e+=t.join(""))}for(const t of s)if("id"!==t&&"class"!==t)try{const n=o.getAttribute(t);n&&(e+=`[${t}="${n.replace(/"/g,'\\"')}"]`)}catch(e){}}catch(t){e=o.tagName?.toLowerCase()||"*"}l.unshift(e||"*"),r=l.join(" > ");try{if(1===n.querySelectorAll(r).length)return r}catch(e){l.shift(),r=l.join(" > ")}try{o=o.parentElement}catch(e){break}a++}return r||"*"}},k=["log","info","warn","error","assert","trace"],x=class extends H{constructor(){super(...arguments),this.originalConsole=null,this.isInitialized=!1}initialize(){if(!this.isInitialized)try{this.originalConsole=this.captureConsoleMethods(),k.forEach((e=>{e in console&&(console[e]=(...t)=>{try{this.handleEvent(t,e)}catch(e){h(e)}finally{this.originalConsole?.[e]&&this.originalConsole[e](...t)}})})),this.isInitialized=!0}catch(e){h(e)}}destroy(){try{if(!this.isInitialized)return;k.forEach((e=>{this.originalConsole&&this.originalConsole[e]&&(console[e]=this.originalConsole[e])})),this.isInitialized=!1}catch(e){h(e)}}handleEvent(e,t){try{if(!S())return;const n=this.formatMessage(Array.isArray(e)?e:[e],t);if(!n||n?.includes("groundcoverIgnore"))return;const i=this.buildEvent({message:n,level:t});this.queueEvent(i)}catch(e){h(e)}}buildEvent({message:e,level:t}){return T({type:"log",attributes:{message:q({text:e}),level:t}})}queueEvent(e){try{this.logger.log("[logs-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}formatMessage(e,t){if(!Array.isArray(e))return String(e);try{return e.map((e=>{if(void 0===e)return"undefined";if(null===e)return"null";if("object"==typeof e){if(e instanceof Error)try{return"error"===t&&e.stack||e.toString()}catch{try{const t={name:e.name,message:e.message,stack:e.stack};return JSON.stringify(t)}catch{return Object.prototype.toString.call(e)}}try{return JSON.stringify(e)}catch{return Object.prototype.toString.call(e)}}return String(e)})).join(" ")}catch(e){return h(e),"[Error formatting console message]"}}captureConsoleMethods(){const e={};try{k.forEach((t=>{console&&"function"==typeof console[t]&&(e[t]=console[t].bind(console))}))}catch(e){h(e)}return e}};function P(e){try{if(null==e)return"";if("string"==typeof e)return e;if(e instanceof FormData)return"[form data]";if(e instanceof Blob)return"[blob data]";if(e instanceof ArrayBuffer)return"[arraybuffer data]";if("undefined"!=typeof Document){if(e instanceof Document)return"[document data]";const t=e;if(9===t?.nodeType)return"[document data]"}if(e instanceof URLSearchParams)try{return e.toString()}catch{return"[unreadable body]"}return Array.isArray(e)||"object"==typeof e?JSON.stringify(e):String(e)}catch(e){return h(`Failed to format body: ${e}`),"[unreadable body]"}}var A=class extends H{constructor(){super(...arguments),this.maxBodyLength=5e3,this.config=m.getInstance(),this.idGenerator=new v,this.handleEvent=e=>{try{if(this.shouldIgnoreRequest(e.url))return;if(!S())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){h(e)}},this.buildEvent=e=>{let t=e.url,n=e.url;this.logger.log("[network-events-listener.buildEvent] called",{event:e});try{t=new URL(e.url).pathname}catch(t){n=new URL(e.url,globalThis.location.href).href}this.logger.log("[network-events-listener.buildEvent] fullUrl",{fullUrl:n});const i=this.formatHeaders(e.request.headers),s=this.formatHeaders(e.response.headers),r=e.method?.toUpperCase()||"UNKNOWN",{traceId:a,spanId:o}=this.extractTraceIds(e.request.headers),l=q({text:e.request.body,maxLength:this.maxBodyLength}),d=q({text:e.response.body,maxLength:this.maxBodyLength}),c={type:"HTTP",operation:{name:r},resource_name:t,status:e.status?.toString(),subType:r,url:{full:n},http:{route:t,path:t,method:e.method,status:e.status?.toString(),request:{headers:i,method:e.method},response:{headers:s,status_code:e.status?.toString()}},error:e?.error?.type?{type:e.error?.type||"Unknown error"}:void 0,gc:{request:{body:l},response:{body:d}}},g={type:"network",timestamp:e?.timestamp&&!Number.isNaN(e.timestamp)?1e6*e.timestamp:void 0,end_timestamp:e?.end_time&&!Number.isNaN(e.end_time)?1e6*e.end_time:void 0,span_name:`${e.method} ${t}`,attributes:c};return a&&(g.traceId=a),o&&(g.spanId=o),T(g)}}async getResponseBody(e){let t;try{const n=e.clone().body;if(n){let e,i=n.getReader(),s=new TextDecoder,r="";for(;!(e=await i.read()).done;){let t=e.value;r+=s.decode(t)}t=r}else t=""}catch(e){t=`Unable to clone response: ${e}`}return t}initialize(){this.logger.log("[network-events-listener.initialize] called"),this.patchXHR(),this.patchFetch()}destroy(){globalThis.XMLHttpRequest.prototype.open=globalThis.XMLHttpRequest.prototype.open,globalThis.XMLHttpRequest.prototype.send=globalThis.XMLHttpRequest.prototype.send,globalThis.fetch=globalThis.fetch}shouldIgnoreRequest(e){try{const t=this.config.getConfig()?.getEndpoint();if(t&&e.includes(t))return!0;if([".tsx",".jsx",".css"].some((t=>e.toLowerCase().endsWith(t))))return!0;return(this.config.getConfig()?.options?.excludedUrls||[]).some((t=>{if(t instanceof RegExp)return t.test(e);if("string"==typeof t&&(t.includes("*")||t.includes("?"))){const n=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".");return new RegExp(n).test(e)}return e===t}))}catch(e){return h(e),!1}}queueEvent(e){try{this.logger.log("[network-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}patchXHR(){const e=this,t=globalThis.XMLHttpRequest.prototype.open,n=globalThis.XMLHttpRequest.prototype.send,i=globalThis.XMLHttpRequest.prototype.setRequestHeader;let s;globalThis.XMLHttpRequest.prototype.open=function(n,i,r=!0,a,o){if(s=Date.now(),e.shouldIgnoreRequest(i.toString()))return t.apply(this,[n,i,r,a,o]);const l=new URL(i.toString(),globalThis.location.href).href;return this._requestMethod=n,this._requestUrl=l,this._requestHeaders={},t.apply(this,[n,i,r,a,o])},globalThis.XMLHttpRequest.prototype.setRequestHeader=function(e,t){return this._requestHeaders&&(this._requestHeaders[e]=t),i.apply(this,[e,t])},globalThis.XMLHttpRequest.prototype.send=function(...t){const i=this._requestUrl?.toString();if(!i||e.shouldIgnoreRequest(i))return n.apply(this,t);if(e.shouldAddTraceHeader(i)){const t=e.config.getConfig(),n=e.getTraceIds();t?.options?.traceOrigin?.name&&e.addHeaderToXhrRequest({request:this,headerName:t.options.traceOrigin.name,headerValue:t.options.traceOrigin.value}),n&&(t?.options?.tracePropagationTraceIdHeaderName&&e.addHeaderToXhrRequest({request:this,headerName:t.options.tracePropagationTraceIdHeaderName,headerValue:n.decimalTraceId}),t?.options?.tracePropagationSpanIdHeaderName&&e.addHeaderToXhrRequest({request:this,headerName:t.options.tracePropagationSpanIdHeaderName,headerValue:n.decimalSpanId}),Boolean(t?.options?.tracePropagationHeaders)&&t?.options?.tracePropagationHeaders?.forEach((t=>{e.addHeaderToXhrRequest({request:this,headerName:t,headerValue:n.traceparent})})),t?.options?.tracePropagationHeaders?.length||e.addHeaderToXhrRequest({request:this,headerName:"traceparent",headerValue:n.traceparent}))}return this._requestBody=t[0]||"",this.addEventListener("load",(()=>{const t=Date.now(),n={};this.getAllResponseHeaders().split(/\r?\n/).forEach((e=>{const[t,i]=e.split(": ");t&&i&&(n[t.trim()]=i.trim())}));const i=P(this._requestBody),r=P(""===this.responseType||"text"===this.responseType?this.responseText:this.response),a={timestamp:s,end_time:t,method:this._requestMethod,url:this._requestUrl,body:i,status:this.status,request:{headers:this._requestHeaders||{},body:i},response:{headers:n,body:r}};e.handleEvent(a)})),n.apply(this,t)}}normalizeHeaders(e,t){try{const n=e?new Headers(e):new Headers;return t?(t instanceof Headers?t.forEach(((e,t)=>n.set(t,e))):Array.isArray(t)?new Headers(t).forEach(((e,t)=>n.set(t,e))):"object"==typeof t&&Object.entries(t).forEach((([e,t])=>n.set(e,t))),n):n}catch{return new Headers}}addTraceHeaders(e){const t=this.config.getConfig(),n=this.getTraceIds();if(t?.options?.traceOrigin?.name&&this.addHeaderToFetchRequest({init:e,headerName:t.options.traceOrigin.name,headerValue:t.options.traceOrigin.value}),!n)return;t?.options?.tracePropagationTraceIdHeaderName&&this.addHeaderToFetchRequest({init:e,headerName:t.options.tracePropagationTraceIdHeaderName,headerValue:n.decimalTraceId}),t?.options?.tracePropagationSpanIdHeaderName&&this.addHeaderToFetchRequest({init:e,headerName:t.options.tracePropagationSpanIdHeaderName,headerValue:n.decimalSpanId});const i=t?.options?.tracePropagationHeaders;(i?.length?i:["traceparent"]).forEach((t=>{this.addHeaderToFetchRequest({init:e,headerName:t,headerValue:n.traceparent})}))}extractHeadersRecord(e){const t={};return e instanceof Headers&&e.forEach(((e,n)=>{t[n]=e})),t}patchFetch(){const e=globalThis.fetch;globalThis.fetch=(...t)=>{const n=Date.now();let[i,s]=t;s={...s||{}},t[1]=s;const r=i instanceof Request,a=s?.method||"GET",o=s?.body||"",l=i instanceof Request?i.url:i.toString();if(this.shouldIgnoreRequest(l))return e.apply(globalThis,t);const d=this.shouldAddTraceHeader(l);s||(t[1]={},s=t[1]),s.headers=this.normalizeHeaders(r?i.headers:void 0,s.headers),d&&this.addTraceHeaders(s);const c=this.extractHeadersRecord(s.headers),g=P(o);return e.apply(globalThis,t).then((e=>{const t=Date.now(),i=e.clone(),s={};i.headers.forEach(((e,t)=>{s[t]=e}));const r={method:a,url:l,timestamp:n,body:g,status:i.status,end_time:t,request:{headers:c,body:g},response:{headers:s,body:""}};try{s["content-type"]?.includes("text/event-stream")?(r.response.body="[unreadable response body]",this.handleEvent(r)):this.getResponseBody(i).then((e=>{r.response.body=e,this.handleEvent(r)})).catch((e=>{r.response.body="[unreadable response body]",this.handleEvent(r),this.logger.log("[network-events-listener.patchFetch] error",{error:e})}))}catch(e){r.response.body="[unreadable response body]",this.handleEvent(r),this.logger.log("[network-events-listener.patchFetch] error",{error:e})}return e})).catch((e=>{const t=Date.now();let n="NetworkError";const i=e.message||"Unknown network error";e instanceof TypeError&&i.includes("Failed to fetch")?n="ERR_NETWORK_FAILURE":i.includes("Name not resolved")?n="ERR_NAME_NOT_RESOLVED":i.includes("Connection refused")&&(n="ERR_CONNECTION_REFUSED");const s={method:a,url:l,body:g,status:0,end_time:t,request:{headers:c,body:g},response:{headers:{},body:""},error:{type:n}};throw this.handleEvent(s),e}))}}formatHeaders(e){const t=["authorization","cookie","set-cookie"];return Object.entries(e)?.reduce(((e,[n,i])=>{const s=n.toLowerCase();return t.includes(s)||/(token|key|secret|password)/i.test(s)?e[n]="[REDACTED]":e[n]=q({text:i}),e}),{})}extractTraceIds(e){const t=this.config.getConfig();let n="",i="";if(t?.options?.tracePropagationTraceIdHeaderName){const i=e[t.options.tracePropagationTraceIdHeaderName];i&&"string"==typeof i&&(n=i)}if(t?.options?.tracePropagationSpanIdHeaderName){const n=e[t.options.tracePropagationSpanIdHeaderName];n&&"string"==typeof n&&(i=n)}if(!n||!i){const t=this.extractTraceparentHeader(e);if(t){const e=t.split("-");4===e.length&&"00"===e[0]&&(!n&&e[1]&&32===e[1].length&&(n=e[1]),!i&&e[2]&&16===e[2].length&&(i=e[2]))}}return{traceId:n,spanId:i}}extractTraceparentHeader(e){const t=this.config.getConfig();if(t?.options?.tracePropagationHeaders?.length)for(const n of t.options.tracePropagationHeaders){const t=e[n];if(t&&"string"==typeof t)return t}const n=e.traceparent;return n&&"string"==typeof n?n:""}getTraceIds(){const e=this.idGenerator.generateSpanId(),t=this.idGenerator.generateTraceId();let n,i;try{n=BigInt("0x"+t).toString(10),i=BigInt("0x"+e).toString(10)}catch(s){this.logger.log("[network-events-listener.getTraceIds] error",{error:s}),n=t,i=e}return{traceparent:`00-${t}-${e}-01`,traceId:t,spanId:e,decimalTraceId:n,decimalSpanId:i}}addHeaderToXhrRequest({request:e,headerName:t,headerValue:n}){if(this.logger.log("[network-events-listener.addHeaderToXhrRequest] called",{request:e,headerName:t,headerValue:n}),this.isValidHeaderName(t))try{e.setRequestHeader(t,n),e._requestHeaders[t]=n}catch(e){this.logger.log("[network-events-listener.addHeaderToXhrRequest] Error setting header",{error:e,headerName:t,headerValue:n})}else this.logger.log("[network-events-listener.addHeaderToXhrRequest] Invalid header name",{headerName:t})}addHeaderToFetchRequest({init:e,headerName:t,headerValue:n}){if(this.logger.log("[network-events-listener.addHeaderToFetchRequest] called",{init:e,headerName:t,headerValue:n}),this.isValidHeaderName(t))try{e.headers instanceof Headers?e.headers.set(t,n):e.headers={...e.headers,[t]:n}}catch(e){this.logger.log("[network-events-listener.addHeaderToFetchRequest] Error setting header",{error:e,headerName:t,headerValue:n})}else this.logger.log("[network-events-listener.addHeaderToFetchRequest] Invalid header name",{headerName:t})}isValidHeaderName(e){if(!e||"string"!=typeof e)return!1;return/^[a-zA-Z0-9!#$&'*+\-.^_`|~]+$/.test(e)}shouldAddTraceHeader(e){const t=this.config.getConfig();if(this.logger.log("[network-events-listener.shouldAddTraceHeader] called",{url:e,config:t}),!t?.options?.tracePropagationUrls?.length)return!1;const n=t.options.tracePropagationUrls?.some((t=>{const n=t.replace(/\*/g,".*"),i=new RegExp(`^${n}$`),s=e.startsWith("/")?new URL(e,globalThis.location.href).pathname:e;return i.test(s)}));return this.logger.log("[network-events-listener.shouldAddTraceHeader] result",{url:e,result:n}),n}},D=class extends H{constructor(){super(...arguments),this.handleEvent=(e,t)=>{this.logger.log("[errors-events-listener.handleEvent] called");try{let n;if(e instanceof Error)n=e,this.enhanceError(n);else if(e instanceof ErrorEvent){if(n=e.error||new Error(e.message||"Unknown error"),/Script error\.?/.test(n.message))return;this.enhanceError(n,e)}else{if(!(e instanceof PromiseRejectionEvent))return;n=this.createUnhandledRejectionError(e)}const i=this.buildEvent(n,t);this.queueEvent(i)}catch(e){h(e)}}}initialize(){f?.addEventListener("error",this.handleEvent),f?.addEventListener("unhandledrejection",this.handleEvent)}destroy(){f?.removeEventListener("error",this.handleEvent),f?.removeEventListener("unhandledrejection",this.handleEvent)}buildEvent(e,t){return T({type:"exception",attributes:{error_type:e.name||"Error",error_message:e.message||"Unknown error",error_stacktrace:this.buildStackTrace(e),error_fingerprint:`${e.name}:${q({text:e.message,maxLength:400})}`,error_handled:t?.handled||!1,error_metadata:t?.metadata}})}queueEvent(e){try{this.logger.log("[errors-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}enhanceError(e,t){const{filename:n,lineno:i,colno:s}=t||{};n&&!e.fileName&&Object.defineProperty(e,"fileName",{value:n}),i&&!e.lineNumber&&Object.defineProperty(e,"lineNumber",{value:i}),s&&!e.columnNumber&&Object.defineProperty(e,"columnNumber",{value:s})}createUnhandledRejectionError(e){let t;if(e.reason instanceof Error)t=e.reason;else{const n="object"==typeof e.reason?JSON.stringify(e.reason,null,2):String(e.reason);t=new Error(n),t.name="UnhandledRejection",Object.defineProperty(t,"originalReason",{value:e.reason,enumerable:!1})}return t}buildStackTrace(e){if(!e)return[];try{return n.parse(e).map((e=>({filename:e.fileName||"unknown",function:e.functionName||"anonymous",lineno:e.lineNumber||0,colno:e.columnNumber||0})))}catch(e){return[]}}},M=class extends H{constructor({isEnabled:e}){if(super(),this.currentUrl="",this.originalPushState=null,this.originalReplaceState=null,this.isInitialized=!1,this.isAutomaticNavigationEnabled=!1,this.activeNavigation=null,this.popStateHandler=()=>{this.handleLocationChange()},this.hashChangeHandler=()=>{this.handleLocationChange()},this.isInBrowserEnvironment()&&e)try{this.isAutomaticNavigationEnabled=e,this.currentUrl=f.location.href,this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState}catch(e){h(e)}}isInBrowserEnvironment(){try{return void 0!==f&&void 0!==f.location&&void 0!==f.history&&"function"==typeof f.addEventListener}catch(e){return h(e),!1}}initialize(){try{if(this.logger.log("[navigation-listener.initialize] called"),!this.isInBrowserEnvironment()||!this.originalPushState||!this.originalReplaceState)return void this.logger.log("[navigation-listener.initialize] Browser environment not available, skipping initialization");if(!this.isAutomaticNavigationEnabled)return void this.logger.log("[navigation-listener.initialize] Automatic navigation is disabled, skipping initialization");const e=this.originalPushState,t=this.originalReplaceState;history.pushState=(...t)=>{const n=e.apply(history,t);return this.handleLocationChange(),n},history.replaceState=(...e)=>{const n=t.apply(history,e);return this.handleLocationChange(),n},f&&"function"==typeof f.addEventListener&&(f.addEventListener("popstate",this.popStateHandler),f.addEventListener("hashchange",this.hashChangeHandler)),this.isInitialized=!0}catch(e){h(e)}}destroy(){try{this.logger.log("[navigation-listener.destroy] called"),this.isInitialized&&this.originalPushState&&this.originalReplaceState&&(history.pushState=this.originalPushState,history.replaceState=this.originalReplaceState),f&&"function"==typeof f.removeEventListener&&(f.removeEventListener("popstate",this.popStateHandler),f.removeEventListener("hashchange",this.hashChangeHandler)),this.isInitialized=!1}catch(e){h(e)}}handleEvent(){try{this.logger.log("[navigation-listener.handleEvent] called");const e=this.buildEvent();this.queueEvent(e)}catch(e){h(e)}}buildEvent(){this.logger.log("[navigation-listener.buildEvent] called",f.location.href);return T({type:"navigation",attributes:{page_url:f.location.href,metadata:this.activeNavigation?.metadata,duration_ms:this.activeNavigation?.duration_ms||0,start_timestamp:this.activeNavigation?.startTime||0,end_timestamp:this.activeNavigation?.endTime||0}})}queueEvent(e){try{this.logger.log("[navigation-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}startNavigation(e){this.logger.log("[navigation-listener.startNavigation] called",e),this.activeNavigation={page_url:f.location.href,metadata:e,startTime:Date.now(),endTime:0,duration_ms:0}}endNavigation(e){this.logger.log("[navigation-listener.endNavigation] called",e),this.activeNavigation?(this.logger.log("[navigation-listener.endNavigation] active navigation",this.activeNavigation),this.activeNavigation.endTime=Date.now(),this.activeNavigation.duration_ms=this.activeNavigation.endTime-this.activeNavigation.startTime,this.handleEvent()):this.logger.log("[navigation-listener.endNavigation] no active navigation found")}handleLocationChange(){try{if(!this.isInitialized)return;if(this.logger.log("[navigation-listener.handleLocationChange] called"),this.currentUrl===f.location.href)return;let e,t;try{e=new URL(f.location.href),t=new URL(this.currentUrl)}catch(e){return void h(e)}const n=e=>e.startsWith("#/"),i=n(e.hash)||n(t.hash);(e.pathname!==t.pathname||i&&e.hash!==t.hash)&&(this.currentUrl=f.location.href,this.handleEvent())}catch(e){h(e)}}},U=class extends H{constructor(){super(),this.loadEventHandler=()=>{this.logger.log("load event"),this.handleEvent()}}initialize(){try{this.logger.log("[page-load-listener.initialize] called"),this.logger.log("globalThis",f),"complete"===f?.document?.readyState?(this.logger.log("Page already loaded, triggering event immediately"),this.handleEvent()):f?.addEventListener("load",this.loadEventHandler)}catch(e){this.logger.log("[page-load-listener.initialize] error",e),h(e)}}destroy(){f?.removeEventListener("load",this.loadEventHandler)}handleEvent(){try{this.logger.log("[page-load-listener.handleEvent] called");const e=this.buildEvent();this.queueEvent(e)}catch(e){h(e)}}buildEvent(){const e=performance.getEntriesByType("navigation")[0],t=e?e.loadEventEnd-e.startTime:0,n=performance.getEntriesByType("resource"),i={count:n.length,totalSize:0,totalDuration:0,byType:{}};n.forEach((e=>{const t=e,n=t.transferSize||0,s=t.duration,r=t.initiatorType;i.totalSize+=n,i.totalDuration+=s,i.byType[r]||(i.byType[r]={count:0,size:0,duration:0}),i.byType[r].count++,i.byType[r].size+=n,i.byType[r].duration+=s}));return T({type:"pageload",attributes:{page_url:f?.location?.href||"",page_load_time:t,page_referrer:f?.document?.referrer||"",page_resources:i}})}queueEvent(e){try{this.logger.log("[page-load-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}},j=class extends H{constructor(){super(...arguments),this.handleEvent=e=>{try{if(!S())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){h(e)}}}initialize(){i(this.handleEvent),s(this.handleEvent),r(this.handleEvent),a(this.handleEvent),o(this.handleEvent)}destroy(){}buildEvent(e){return T({type:"performance",attributes:{performance_metric_name:e.name,performance_metric_value:e.value,performance_metric_id:e.id,performance_metric_navigation_type:e.navigationType||""}})}queueEvent(e){try{this.logger.log("[performance-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){h(e)}}};function O(e){try{return btoa(encodeURIComponent(JSON.stringify(e)))}catch(e){throw h(e),new Error(`Failed to convert to base64: ${e instanceof Error?e.message:String(e)}`)}}var F,$=class{constructor(){this.logger=c.getInstance(),this.eventsPool=C.getInstance(),this.stopFn=null,this.isRecording=!1,this.events=[],this.startTime=0,this.batchSize=10}initialize(){this.logger.log("[session-replay-listener] initialize called"),this.isRecording?this.logger.log("[session-replay-listener] already recording"):this.startRecording()}startRecording(){try{this.startTime=Date.now(),this.events=[],this.isRecording=!0,this.stopFn=l({emit:e=>{if(this.isRecording)try{if(this.events.push({type:e.type,data:e.data,timestamp:e.timestamp||Date.now()}),this.events.length>=this.batchSize)try{this.sendBatch()}catch(e){h(e),this.logger.log("[session-replay-listener] failed to send batch in emit callback:",e)}}catch(e){h(e),this.logger.log("[session-replay-listener] failed to process event in emit callback:",e)}}})||null,this.logger.log("[session-replay-listener] started recording")}catch(e){h(e),this.logger.log("[session-replay-listener] failed to start recording:",e),this.isRecording=!1}}sendBatch(){if(0!==this.events.length)try{const e=[...this.events],t=T({type:"replay",attributes:{replay_data:{events:O(e)}}});this.eventsPool.addEvent(t),this.events=[],this.logger.log("[session-replay-listener] sent batch with",e.length,"events")}catch(e){h(e),this.logger.log("[session-replay-listener] failed to send batch:",e)}}stopRecording(){if(this.isRecording&&this.stopFn)try{this.stopFn(),this.isRecording=!1;const e=this.events.length;if(e>0)try{const t=T({type:"replay",attributes:{replay_data:{events:O(this.events)}}});this.eventsPool.addEvent(t),this.logger.log("[session-replay-listener] sent final replay event with",e,"events")}catch(e){h(e),this.logger.log("[session-replay-listener] failed to encode and send final replay event:",e)}this.stopFn=null}catch(e){h(e),this.logger.log("[session-replay-listener] failed to stop recording:",e)}}destroy(){this.stopRecording()}},X=class{constructor(){this.logger=c.getInstance(),this.eventsPool=C.getInstance(),this.configManager=m.getInstance(),this.logEventsListener=null,this.domEventsListener=null,this.errorsEventsListener=null,this.networkEventsListener=null,this.navigationListener=null,this.performanceListener=null,this.pageLoadListener=null,this.sessionReplayListener=null}instrument(){this.logger.log("[instrumentation-manager.instrument] called");const e=this.configManager.getConfig(),t=e?.options?.enabledEvents,n=!t||0===t.length,i=[];(n||t?.includes("pageload"))&&(this.pageLoadListener=new U,this.pageLoadListener.initialize(),i.push("pageload")),(n||t?.includes("dom"))&&(this.domEventsListener=new _,this.domEventsListener.initialize(),i.push("dom")),(n||t?.includes("logs"))&&(this.logEventsListener=new x,this.logEventsListener.initialize(),i.push("logs")),(n||t?.includes("exceptions"))&&(this.errorsEventsListener=new D,this.errorsEventsListener.initialize(),i.push("exceptions")),(n||t?.includes("network"))&&(this.networkEventsListener=new A,this.networkEventsListener.initialize(),i.push("network")),(n||t?.includes("performance"))&&(this.performanceListener=new j,this.performanceListener.initialize(),i.push("performance")),this.navigationListener=new M({isEnabled:n||t?.includes("navigation")}),this.navigationListener.initialize(),i.push("navigation"),this.logger.log("[instrumentation-manager.instrument] initialized listeners based on config:",i)}sendCustomEvent(e){this.logger.log("[instrumentation-manager.sendCustomEvent] called",e);try{const t=T({type:"custom",attributes:{custom_event_name:e?.event,custom_event_attributes:e?.attributes}});this.eventsPool.addEvent(t)}catch(e){h(e)}}captureException(e,t){try{this.logger.log("[instrumentation-manager.captureException] called",e),this.errorsEventsListener?.handleEvent(e,{handled:!0,metadata:t})}catch(e){h(e)}}isNavigationTrackingEnabled(){const e=this.configManager.getConfig();return e?.options?.enabledEvents?.includes("navigation")||0===e?.options?.enabledEvents?.length}startNavigation(e){this.logger.log("[instrumentation-manager.startNavigation] called",e),this.isNavigationTrackingEnabled()?this.logger.log("[instrumentation-manager.startNavigation] startNavigation called while navigation tracking is enabled. Ignoring. If you wish to track navigations manually, please disable navigation tracking via the enabledEvents array in the config."):this.navigationListener?.startNavigation(e)}endNavigation(e){this.logger.log("[instrumentation-manager.endNavigation] called",e),this.isNavigationTrackingEnabled()?this.logger.log("[instrumentation-manager.endNavigation] endNavigation called while navigation tracking is enabled. Ignoring. If you wish to track navigations manually, please disable navigation tracking via the enabledEvents array in the config."):this.navigationListener?.endNavigation(e)}startReplayRecording(){this.sessionReplayListener?this.logger.log("[instrumentation-manager] replay recording already started"):(this.sessionReplayListener=new $,this.sessionReplayListener.initialize(),this.logger.log("[instrumentation-manager] started replay recording"))}stopReplayRecording(){this.sessionReplayListener?(this.sessionReplayListener.stopRecording(),this.sessionReplayListener=null):this.logger.log("[instrumentation-manager] cannot stop replay recording: replay listener not initialized")}uninstrument(){this.domEventsListener?.destroy(),this.logEventsListener?.destroy(),this.errorsEventsListener?.destroy(),this.networkEventsListener?.destroy(),this.navigationListener?.destroy(),this.performanceListener?.destroy(),this.pageLoadListener?.destroy(),this.sessionReplayListener?.destroy()}},K="gcSample",B=class{constructor(e){this.initialized=!1,this.logger=c.initialize({debug:e.options?.debug||!1,prefix:"[groundcover]"}),this.logger.log("[session-manager] initialize called"),this.instrumentationManager=new X,this.idGenerator=new v;if(!this.getSamplingDecision(e.options?.sessionSampleRate))return void this.logger.log("[session-manager] session is not sampled");if(this.initialized)return void this.logger.log("[session-manager] SDK already initialized");const t=m.getInstance();t.initialize(e);C.getInstance().initialize();const n=e.sessionId,i=t.getSessionId();n?(t.setSessionId(n),this.logger.log("[session-manager] using provided sessionId:",n)):i||t.setSessionId(this.idGenerator.generateId()),this.instrumentationManager.instrument(),this.initialized=!0}getSamplingDecision(e){try{if(!e||1===e)return!0;const t=globalThis.sessionStorage?.getItem(K);if(t){const e="1"===t;return this.logger.log("[session-manager] using stored sampling decision:",e),e}const n=!e||Math.random()<e;return globalThis?.sessionStorage?.setItem(K,n?"1":"0"),this.logger.log("[session-manager] stored new sampling decision:",n),n}catch(t){this.logger.log("[session-manager] session storage access failed:",t);const n=!e||Math.random()<e;return this.logger.log("[session-manager] using fallback sampling decision:",n),n}}identifyUser(e){if(this.logger.log("[session-manager] identifyUser called"),!this.initialized)return void this.logger.log("[session-manager] cannot identify user: SDK not initialized");m.getInstance().updateConfig({userIdentifier:e})}updateConfig(e){if(!this.initialized)return void this.logger.log("[session-manager] cannot update config: SDK not initialized");m.getInstance().updateConfig(e)}sendCustomEvent(e){this.initialized?this.instrumentationManager.sendCustomEvent(e):this.logger.log("[session-manager] cannot send custom event: SDK not initialized")}startNavigation(e){this.initialized?this.instrumentationManager.startNavigation(e):this.logger.log("[session-manager] cannot start navigation: SDK not initialized")}endNavigation(e){this.initialized?this.instrumentationManager.endNavigation(e):this.logger.log("[session-manager] cannot end navigation: SDK not initialized")}captureException(e,t){this.initialized?this.instrumentationManager.captureException(e,t):this.logger.log("[session-manager] Cannot capture exception: SDK not initialized")}async setSessionId(e){if(this.logger.log("[session-manager] setSessionId called"),this.initialized)try{const t=C.getInstance();await t.flushSync();const n=e||this.idGenerator.generateId();m.getInstance().setSessionId(n),this.logger.log("[session-manager] session ID set successfully:",n)}catch(e){this.logger.log("[session-manager] failed to set session ID:",e)}else this.logger.log("[session-manager] cannot set session ID: SDK not initialized")}startReplayRecording(){this.initialized?this.instrumentationManager.startReplayRecording():this.logger.log("[session-manager] cannot start replay recording: SDK not initialized")}stopReplayRecording(){this.initialized?this.instrumentationManager.stopReplayRecording():this.logger.log("[session-manager] cannot stop replay recording: SDK not initialized")}destroy(){this.initialized&&(this.instrumentationManager.uninstrument(),globalThis.sessionStorage?.removeItem("gcId"),this.initialized=!1)}};var V={init:function(e){try{F=new B({cluster:e?.cluster||"",environment:e?.environment||"",namespace:e?.namespace,dsn:e?.dsn||"",appId:e?.appId||"",userIdentifier:e?.userIdentifier,apiKey:e?.apiKey||"",options:e?.options,sessionId:e?.sessionId})}catch(e){h(e)}},identifyUser:function(e){F?F.identifyUser(e):console.warn("[groundcover] identifyUser: groundcover is not initialized. please call init() first")},sendCustomEvent:function(e){F&&F.sendCustomEvent(e)},captureException:function(e,t){F&&F.captureException(e,t)},updateConfig:function(e){F&&F.updateConfig(e)},startNavigation:function(e){F?F.startNavigation(e):console.warn("[groundcover] startNavigation: groundcover is not initialized. please call init() first")},endNavigation:function(e){F?F.endNavigation(e):console.warn("[groundcover] endNavigation: groundcover is not initialized. please call init() first")},setSessionId:async function(e){if(F)try{await F.setSessionId(e)}catch(e){console.error("[groundcover] setSessionId: failed to set session ID:",e)}else console.warn("[groundcover] setSessionId: groundcover is not initialized. please call init() first")},startReplayRecording:function(){F?F.startReplayRecording():console.warn("[groundcover] startReplayRecording: groundcover is not initialized. please call init() first")},stopReplayRecording:function(){F?F.stopReplayRecording():console.warn("[groundcover] stopReplayRecording: groundcover is not initialized. please call init() first")}};if("undefined"!=typeof window&&!window.groundcover)try{window.groundcover=V}catch(e){console.warn("[groundcover] Failed to expose groundcover on window:",e)}var W=V;export{W as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groundcover/browser",
3
- "version": "0.0.58",
3
+ "version": "0.0.60",
4
4
  "description": "groundcover browser SDK",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -45,22 +45,24 @@
45
45
  "terser": "^5.39.0",
46
46
  "tslib": "^2.8.1",
47
47
  "tsup": "^8.4.0",
48
+ "typescript": "~5.7.2",
48
49
  "typescript-eslint": "^8.22.0",
49
50
  "vitest": "^3.0.8"
50
51
  },
51
52
  "dependencies": {
52
- "error-stack-parser": "^2.1.4",
53
- "fflate": "^0.8.2",
54
- "web-vitals": "^4.2.4"
53
+ "error-stack-parser": "2.1.4",
54
+ "fflate": "0.8.2",
55
+ "rrweb": "2.0.0-alpha.18",
56
+ "web-vitals": "4.2.4"
55
57
  },
56
58
  "size-limit": [
57
59
  {
58
60
  "path": "dist/index.js",
59
- "limit": "30 kB"
61
+ "limit": "80 kB"
60
62
  },
61
63
  {
62
64
  "path": "dist/index.mjs",
63
- "limit": "30 kB"
65
+ "limit": "80 kB"
64
66
  }
65
67
  ]
66
68
  }