@groundcover/browser 0.0.51 → 0.0.53-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/dist/index.d.mts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +13 -11
package/README.md
CHANGED
|
@@ -24,6 +24,35 @@ groundcover.init({
|
|
|
24
24
|
});
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
### Micro-frontend Session Synchronization
|
|
28
|
+
|
|
29
|
+
For micro-frontend architectures, you can synchronize sessions across different frontend applications by passing a shared sessionId:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
// Main application generates a sessionId
|
|
33
|
+
const sharedSessionId = "session-12345";
|
|
34
|
+
|
|
35
|
+
// Initialize SDK in main app
|
|
36
|
+
groundcover.init({
|
|
37
|
+
apiKey: "your-api-key",
|
|
38
|
+
cluster: "your-cluster",
|
|
39
|
+
environment: "production",
|
|
40
|
+
dsn: "your-dsn",
|
|
41
|
+
appId: "your-app-id",
|
|
42
|
+
sessionId: sharedSessionId, // Use shared sessionId
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Initialize SDK in micro-frontend with same sessionId
|
|
46
|
+
groundcover.init({
|
|
47
|
+
apiKey: "your-api-key",
|
|
48
|
+
cluster: "your-cluster",
|
|
49
|
+
environment: "production",
|
|
50
|
+
dsn: "your-dsn",
|
|
51
|
+
appId: "micro-frontend-app-id",
|
|
52
|
+
sessionId: sharedSessionId, // Same sessionId for session continuity
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
27
56
|
## Identify users
|
|
28
57
|
|
|
29
58
|
Link RUM data to specific users:
|
|
@@ -77,6 +106,7 @@ groundcover.init({
|
|
|
77
106
|
environment: "production",
|
|
78
107
|
dsn: "your-dsn",
|
|
79
108
|
appId: "your-app-id",
|
|
109
|
+
sessionId: "optional-session-id", // For micro-frontend synchronization
|
|
80
110
|
options: {
|
|
81
111
|
batchSize: 50,
|
|
82
112
|
sessionSampleRate: 0.5, // 50% sessions sampled
|
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;
|
|
@@ -132,6 +132,15 @@ type PerformanceEventAttributes = {
|
|
|
132
132
|
performance_metric_id: string;
|
|
133
133
|
performance_metric_navigation_type: string;
|
|
134
134
|
};
|
|
135
|
+
type ReplayEventAttributes = {
|
|
136
|
+
replay_data: {
|
|
137
|
+
events: Array<{
|
|
138
|
+
type: number;
|
|
139
|
+
data: unknown;
|
|
140
|
+
timestamp: number;
|
|
141
|
+
}> | string;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
135
144
|
|
|
136
145
|
type Event<T extends BaseEvent["type"], A> = Omit<BaseEvent, "attributes"> & {
|
|
137
146
|
type: T;
|
|
@@ -148,11 +157,12 @@ type EventTypes = {
|
|
|
148
157
|
navigation: Event<"navigation", NavigationEventAttributes>;
|
|
149
158
|
custom: Event<"custom", UserDefinedEventAttributes>;
|
|
150
159
|
performance: Event<"performance", PerformanceEventAttributes>;
|
|
160
|
+
replay: Event<"replay", ReplayEventAttributes>;
|
|
151
161
|
};
|
|
152
162
|
interface SDKOptions {
|
|
153
163
|
batchSize: number;
|
|
154
164
|
batchTimeout: number;
|
|
155
|
-
enabledEvents: Array<"dom" | "network" | "exceptions" | "logs" | "pageload" | "navigation" | "performance">;
|
|
165
|
+
enabledEvents: Array<"dom" | "network" | "exceptions" | "logs" | "pageload" | "navigation" | "performance" | "replay">;
|
|
156
166
|
eventSampleRate: number;
|
|
157
167
|
sessionSampleRate: number;
|
|
158
168
|
environment: string;
|
|
@@ -181,6 +191,7 @@ interface SDKConfigInput {
|
|
|
181
191
|
namespace?: string;
|
|
182
192
|
userIdentifier?: Partial<UserIdentifiers>;
|
|
183
193
|
options?: Partial<SDKOptions>;
|
|
194
|
+
sessionId?: string;
|
|
184
195
|
}
|
|
185
196
|
|
|
186
197
|
declare class SDKConfig {
|
|
@@ -206,6 +217,7 @@ declare function init(params?: {
|
|
|
206
217
|
dsn?: string;
|
|
207
218
|
options?: Partial<SDKOptions>;
|
|
208
219
|
apiKey?: string;
|
|
220
|
+
sessionId?: string;
|
|
209
221
|
}): void;
|
|
210
222
|
declare function identifyUser(userIdentifier: Partial<UserIdentifiers>): void;
|
|
211
223
|
declare function sendCustomEvent(params: {
|
|
@@ -217,6 +229,7 @@ declare function updateConfig(params: Partial<SDKConfig>): void;
|
|
|
217
229
|
declare function startNavigation(metadata: Record<string, unknown>): void;
|
|
218
230
|
declare function endNavigation(metadata: Record<string, unknown>): void;
|
|
219
231
|
declare function setSessionId(newSessionId?: string): Promise<void>;
|
|
232
|
+
declare function stopReplayRecording(): void;
|
|
220
233
|
declare const _default: {
|
|
221
234
|
init: typeof init;
|
|
222
235
|
identifyUser: typeof identifyUser;
|
|
@@ -226,6 +239,7 @@ declare const _default: {
|
|
|
226
239
|
startNavigation: typeof startNavigation;
|
|
227
240
|
endNavigation: typeof endNavigation;
|
|
228
241
|
setSessionId: typeof setSessionId;
|
|
242
|
+
stopReplayRecording: typeof stopReplayRecording;
|
|
229
243
|
};
|
|
230
244
|
|
|
231
245
|
export { type EventTypes, _default 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;
|
|
@@ -132,6 +132,15 @@ type PerformanceEventAttributes = {
|
|
|
132
132
|
performance_metric_id: string;
|
|
133
133
|
performance_metric_navigation_type: string;
|
|
134
134
|
};
|
|
135
|
+
type ReplayEventAttributes = {
|
|
136
|
+
replay_data: {
|
|
137
|
+
events: Array<{
|
|
138
|
+
type: number;
|
|
139
|
+
data: unknown;
|
|
140
|
+
timestamp: number;
|
|
141
|
+
}> | string;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
135
144
|
|
|
136
145
|
type Event<T extends BaseEvent["type"], A> = Omit<BaseEvent, "attributes"> & {
|
|
137
146
|
type: T;
|
|
@@ -148,11 +157,12 @@ type EventTypes = {
|
|
|
148
157
|
navigation: Event<"navigation", NavigationEventAttributes>;
|
|
149
158
|
custom: Event<"custom", UserDefinedEventAttributes>;
|
|
150
159
|
performance: Event<"performance", PerformanceEventAttributes>;
|
|
160
|
+
replay: Event<"replay", ReplayEventAttributes>;
|
|
151
161
|
};
|
|
152
162
|
interface SDKOptions {
|
|
153
163
|
batchSize: number;
|
|
154
164
|
batchTimeout: number;
|
|
155
|
-
enabledEvents: Array<"dom" | "network" | "exceptions" | "logs" | "pageload" | "navigation" | "performance">;
|
|
165
|
+
enabledEvents: Array<"dom" | "network" | "exceptions" | "logs" | "pageload" | "navigation" | "performance" | "replay">;
|
|
156
166
|
eventSampleRate: number;
|
|
157
167
|
sessionSampleRate: number;
|
|
158
168
|
environment: string;
|
|
@@ -181,6 +191,7 @@ interface SDKConfigInput {
|
|
|
181
191
|
namespace?: string;
|
|
182
192
|
userIdentifier?: Partial<UserIdentifiers>;
|
|
183
193
|
options?: Partial<SDKOptions>;
|
|
194
|
+
sessionId?: string;
|
|
184
195
|
}
|
|
185
196
|
|
|
186
197
|
declare class SDKConfig {
|
|
@@ -206,6 +217,7 @@ declare function init(params?: {
|
|
|
206
217
|
dsn?: string;
|
|
207
218
|
options?: Partial<SDKOptions>;
|
|
208
219
|
apiKey?: string;
|
|
220
|
+
sessionId?: string;
|
|
209
221
|
}): void;
|
|
210
222
|
declare function identifyUser(userIdentifier: Partial<UserIdentifiers>): void;
|
|
211
223
|
declare function sendCustomEvent(params: {
|
|
@@ -217,6 +229,7 @@ declare function updateConfig(params: Partial<SDKConfig>): void;
|
|
|
217
229
|
declare function startNavigation(metadata: Record<string, unknown>): void;
|
|
218
230
|
declare function endNavigation(metadata: Record<string, unknown>): void;
|
|
219
231
|
declare function setSessionId(newSessionId?: string): Promise<void>;
|
|
232
|
+
declare function stopReplayRecording(): void;
|
|
220
233
|
declare const _default: {
|
|
221
234
|
init: typeof init;
|
|
222
235
|
identifyUser: typeof identifyUser;
|
|
@@ -226,6 +239,7 @@ declare const _default: {
|
|
|
226
239
|
startNavigation: typeof startNavigation;
|
|
227
240
|
endNavigation: typeof endNavigation;
|
|
228
241
|
setSessionId: typeof setSessionId;
|
|
242
|
+
stopReplayRecording: typeof stopReplayRecording;
|
|
229
243
|
};
|
|
230
244
|
|
|
231
245
|
export { type EventTypes, _default 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),a=console.log.bind(console),r=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}},o=r.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)}},g=class e{constructor(){this.config=null,this.logger=r.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")}},h="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 v=g.getInstance(),f=new u;function y(){const e=v?.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=f.generateId(),i=e.spanId||f.generateSpanId(),s=e.traceId||f.generateTraceId(),a=e.parentSpanId||"",r=E(e.attributes||{}),o=function(){const e=h?.location;return e?{path:e.hash&&!e.hash.match(/^#[a-z0-9-]+$/i)&&e.hash.startsWith("#/")?e.hash:e.pathname,url:e.href,title:h?.document?.title||""}:{path:"",url:"",title:h?.document?.title||""}}(),l={type:e.type,id:n,spanId:i,parentSpanId:a,traceId:s,attributes:{...r,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=r.getInstance(),this.config=g.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:a,isCompressed:r}=this.compress(s);fetch(i,{method:"POST",headers:{"Content-Type":"application/json",apikey:n,"Content-Encoding":r?"gzip":""},body:a}).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=g.getInstance(),this.logger=r.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&&!T.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&&(h.clearTimeout(this.timeoutId),this.timeoutId=null);const e=this.config.getConfig()?.options?.batchTimeout;if(!e)return;this.timeoutId=h.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}}};N.instance=null;var S=N,w=class{constructor(){this.logger=r.getInstance(),this.eventsPool=S.getInstance()}};function C({text:e,maxLength:t=1e4}){return e?e.length<=t||"string"!=typeof e?e:e.substring(0,t):""}var L,H=class extends w{constructor(){super(...arguments),this.eventHandlers=[],this.capturedEvents=["click","change","keydown","select","submit"],this.config=g.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}),h?.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),a=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:a}}})}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 a="",r=0,o=e;const l=[];for(;o&&o!==n&&o!==document.documentElement&&r<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||"*"),a=l.join(" > ");try{if(1===n.querySelectorAll(a).length)return a}catch(e){l.shift(),a=l.join(" > ")}try{o=o.parentElement}catch(e){break}r++}return a||"*"}},q=["log","info","warn","error","assert","trace"],z=class extends w{constructor(){super(...arguments),this.originalConsole=null,this.isInitialized=!1}initialize(){if(!this.isInitialized)try{this.originalConsole=this.captureConsoleMethods(),q.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;q.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{q.forEach((t=>{console&&"function"==typeof console[t]&&(e[t]=console[t].bind(console))}))}catch(e){l(e)}return e}},R=class extends w{constructor(){super(...arguments),this.maxBodyLength=5e3,this.config=g.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),a=e.method?.toUpperCase()||"UNKNOWN",{traceId:r,spanId:o}=this.extractTraceIds(e.request.headers),l={type:"HTTP",operation:{name:a},resource_name:t,status:e.status?.toString(),subType:a,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:C({text:e.request.body,maxLength:this.maxBodyLength})},response:{body:C({text:e.response.body,maxLength:this.maxBodyLength})}}},d={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:l};return r&&(d.traceId=r),o&&(d.spanId=o),b(d)}}async getResponseBody(e){let t;try{const n=e.clone().body;if(n){let e,i=n.getReader(),s=new TextDecoder,a="";for(;!(e=await i.read()).done;){let t=e.value;a+=s.decode(t)}t=a}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,a=!0,r,o){if(s=Date.now(),e.shouldIgnoreRequest(i.toString()))return t.apply(this,[n,i,a,r,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,a,r,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);const a=e.shouldAddTraceHeader(i);if(e.logger.log("[network-events-listener.patchXHR] test",{shouldAddTraceHeader:a}),a){const t=e.config.getConfig(),n=e.getTraceIds();e.logger.log("[network-events-listener.patchXHR] traceIds",{traceIds:n}),t?.options?.traceOrigin?.name&&e.addHeaderToXhrRequest({request:this,headerName:t.options.traceOrigin.name,headerValue:t.options.traceOrigin.value}),n&&(e.logger.log("[network-events-listener.patchXHR] traceIds",{traceIds:n,names:t?.options?.tracePropagationTraceIdHeaderName,spanIdHeaderName:t?.options?.tracePropagationSpanIdHeaderName,headers:t?.options?.tracePropagationHeaders}),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}),t?.options?.tracePropagationHeaders?t.options.tracePropagationHeaders.forEach((t=>{e.addHeaderToXhrRequest({request:this,headerName:t,headerValue:n.traceparent})})):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())}));let i="";try{i=""===this.responseType||"text"===this.responseType?this.responseText||"":"json"===this.responseType?JSON.stringify(this.response||""):"blob"===this.responseType?"[blob data]":"arraybuffer"===this.responseType?"[arraybuffer data]":"document"===this.responseType?"[document data]":String(this.response||"")}catch(e){i="[unreadable response body]"}const a={timestamp:s,end_time:t,method:this._requestMethod,url:this._requestUrl,body:this._requestBody,status:this.status,request:{headers:this._requestHeaders||{},body:this._requestBody},response:{headers:n,body:i}};e.handleEvent(a)})),n.apply(this,t)}}patchFetch(){const e=globalThis.fetch;globalThis.fetch=(...t)=>{const n=Date.now();let[i,s]=t;s={...s||{}},t[1]=s;const a=s?.method||"GET",r=s?.body||"",o=i instanceof Request?i.url:i.toString();if(this.shouldIgnoreRequest(o))return e.apply(globalThis,t);const l=this.shouldAddTraceHeader(o);if(s||(t[1]={},s=t[1]),s.headers||(s.headers={}),l){const e=this.config.getConfig(),t=this.getTraceIds();e?.options?.traceOrigin?.name&&this.addHeaderToFetchRequest({init:s,headerName:e.options.traceOrigin.name,headerValue:e.options.traceOrigin.value}),t&&(e?.options?.tracePropagationTraceIdHeaderName&&this.addHeaderToFetchRequest({init:s,headerName:e.options.tracePropagationTraceIdHeaderName,headerValue:t.decimalTraceId}),e?.options?.tracePropagationSpanIdHeaderName&&this.addHeaderToFetchRequest({init:s,headerName:e.options.tracePropagationSpanIdHeaderName,headerValue:t.decimalSpanId}),e?.options?.tracePropagationHeaders?e.options.tracePropagationHeaders.forEach((e=>{this.addHeaderToFetchRequest({init:s,headerName:e,headerValue:t.traceparent})})):this.addHeaderToFetchRequest({init:s,headerName:"traceparent",headerValue:t.traceparent}))}const d={};return s?.headers&&(s.headers instanceof Headers?s.headers.forEach(((e,t)=>{d[t]=e})):"object"==typeof s.headers&&Object.assign(d,s.headers)),e.apply(globalThis,t).then((async e=>{const t=Date.now(),i=e.clone();let s="";const l={};i.headers.forEach(((e,t)=>{l[t]=e}));try{s=l["content-type"]?.includes("text/event-stream")?"[unreadable response body]":await this.getResponseBody(i)}catch(e){s="[unreadable response body]"}this.logger.log("[network-events-listener.patchFetch] called",{url:o});const c={method:a,url:o,timestamp:n,body:r.toString(),status:i.status,end_time:t,request:{headers:d,body:r.toString()},response:{headers:l,body:s}};return this.handleEvent(c),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:o,body:r.toString(),status:0,end_time:t,request:{headers:d,body:r.toString()},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}},_=class extends w{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(){h?.addEventListener("error",this.handleEvent),h?.addEventListener("unhandledrejection",this.handleEvent)}destroy(){h?.removeEventListener("error",this.handleEvent),h?.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[]}}},k=class extends w{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=h.location.href,this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState}catch(e){l(e)}}isInBrowserEnvironment(){try{return void 0!==h&&void 0!==h.location&&void 0!==h.history&&"function"==typeof h.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},h&&"function"==typeof h.addEventListener&&(h.addEventListener("popstate",this.popStateHandler),h.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),h&&"function"==typeof h.removeEventListener&&(h.removeEventListener("popstate",this.popStateHandler),h.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",h.location.href);return b({type:"navigation",attributes:{page_url:h.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:h.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===h.location.href)return;let e,t;try{e=new URL(h.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=h.location.href,this.handleEvent())}catch(e){l(e)}}},x=class extends w{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",h),"complete"===h?.document?.readyState?(this.logger.log("Page already loaded, triggering event immediately"),this.handleEvent()):h?.addEventListener("load",this.loadEventHandler)}catch(e){this.logger.log("[page-load-listener.initialize] error",e),l(e)}}destroy(){h?.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,a=t.initiatorType;i.totalSize+=n,i.totalDuration+=s,i.byType[a]||(i.byType[a]={count:0,size:0,duration:0}),i.byType[a].count++,i.byType[a].size+=n,i.byType[a].duration+=s}));return b({type:"pageload",attributes:{page_url:h?.location?.href||"",page_load_time:t,page_referrer:h?.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)}}},P=class extends w{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)}}},M=class{constructor(){this.logger=r.getInstance(),this.eventsPool=S.getInstance(),this.configManager=g.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 x,this.pageLoadListener.initialize(),i.push("pageload")),(n||t?.includes("dom"))&&(this.domEventsListener=new H,this.domEventsListener.initialize(),i.push("dom")),(n||t?.includes("logs"))&&(this.logEventsListener=new z,this.logEventsListener.initialize(),i.push("logs")),(n||t?.includes("exceptions"))&&(this.errorsEventsListener=new _,this.errorsEventsListener.initialize(),i.push("exceptions")),(n||t?.includes("network"))&&(this.networkEventsListener=new R,this.networkEventsListener.initialize(),i.push("network")),(n||t?.includes("performance"))&&(this.performanceListener=new P,this.performanceListener.initialize(),i.push("performance")),this.navigationListener=new k({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()}},A="gcSample",U=class{constructor(e){this.initialized=!1,this.logger=r.initialize({debug:e.options?.debug||!1,prefix:"[groundcover]"}),this.logger.log("[session-manager] initialize called"),this.instrumentationManager=new M,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=g.getInstance();t.initialize(e);S.getInstance().initialize();t.getSessionId()||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(A);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(A,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");g.getInstance().updateConfig({userIdentifier:e})}updateConfig(e){if(!this.initialized)return void this.logger.log("[session-manager] cannot update config: SDK not initialized");g.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=S.getInstance();await t.flushSync();const n=e||this.idGenerator.generateId();g.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 D={init:function(e){try{L=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})}catch(e){l(e)}},identifyUser:function(e){L?L.identifyUser(e):console.warn("[groundcover] identifyUser: groundcover is not initialized. please call init() first")},sendCustomEvent:function(e){L&&L.sendCustomEvent(e)},captureException:function(e){L&&L.captureException(e)},updateConfig:function(e){L&&L.updateConfig(e)},startNavigation:function(e){L?L.startNavigation(e):console.warn("[groundcover] startNavigation: groundcover is not initialized. please call init() first")},endNavigation:function(e){L?L.endNavigation(e):console.warn("[groundcover] endNavigation: groundcover is not initialized. please call init() first")},setSessionId:async function(e){if(L)try{await L.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")}};module.exports=D;
|
|
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:""}},h=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)}},g=class e{coInstructor(){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 h(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=v(16),this.generateSpanId=v(8),this.generateId=v(16)}},m=Array(32);function v(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 f=g.getInstance(),y=new p;function E(){const e=f?.getConfig()?.options?.eventSampleRate;return!(void 0!==e&&!Number.isNaN(e))||Math.random()<=e}function b(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,b(i,s)):e[s]=i,e}),{})}function I(e){const t=1e6*Date.now(),n=y.generateId(),i=e.spanId||y.generateSpanId(),s=e.traceId||y.generateTraceId(),r=e.parentSpanId||"",a=b(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=g.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=g.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 w=N,R=class{constructor(){this.logger=o.getInstance(),this.eventsPool=w.getInstance()}};function L({text:e,maxLength:t=1e4}){return e?e.length<=t||"string"!=typeof e?e:e.substring(0,t):""}var C,H=class extends R{constructor(){super(...arguments),this.eventHandlers=[],this.capturedEvents=["click","change","keydown","select","submit"],this.config=g.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?"*":L({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(!E())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 I({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||"*"}},z=["log","info","warn","error","assert","trace"],q=class extends R{constructor(){super(...arguments),this.originalConsole=null,this.isInitialized=!1}initialize(){if(!this.isInitialized)try{this.originalConsole=this.captureConsoleMethods(),z.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;z.forEach((e=>{this.originalConsole&&this.originalConsole[e]&&(console[e]=this.originalConsole[e])})),this.isInitialized=!1}catch(e){d(e)}}handleEvent(e,t){try{if(!E())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 I({type:"log",attributes:{message:L({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{z.forEach((t=>{console&&"function"==typeof console[t]&&(e[t]=console[t].bind(console))}))}catch(e){d(e)}return e}},_=class extends R{constructor(){super(...arguments),this.maxBodyLength=5e3,this.config=g.getInstance(),this.idGenerator=new p,this.handleEvent=e=>{try{if(this.shouldIgnoreRequest(e.url))return;if(!E())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={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({text:e.request.body,maxLength:this.maxBodyLength})},response:{body:L({text:e.response.body,maxLength:this.maxBodyLength})}}},d={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:l};return a&&(d.traceId=a),o&&(d.spanId=o),I(d)}}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);const r=e.shouldAddTraceHeader(i);if(e.logger.log("[network-events-listener.patchXHR] test",{shouldAddTraceHeader:r}),r){const t=e.config.getConfig(),n=e.getTraceIds();e.logger.log("[network-events-listener.patchXHR] traceIds",{traceIds:n}),t?.options?.traceOrigin?.name&&e.addHeaderToXhrRequest({request:this,headerName:t.options.traceOrigin.name,headerValue:t.options.traceOrigin.value}),n&&(e.logger.log("[network-events-listener.patchXHR] traceIds",{traceIds:n,names:t?.options?.tracePropagationTraceIdHeaderName,spanIdHeaderName:t?.options?.tracePropagationSpanIdHeaderName,headers:t?.options?.tracePropagationHeaders}),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}),t?.options?.tracePropagationHeaders?t.options.tracePropagationHeaders.forEach((t=>{e.addHeaderToXhrRequest({request:this,headerName:t,headerValue:n.traceparent})})):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())}));let i="";try{i=""===this.responseType||"text"===this.responseType?this.responseText||"":"json"===this.responseType?JSON.stringify(this.response||""):"blob"===this.responseType?"[blob data]":"arraybuffer"===this.responseType?"[arraybuffer data]":"document"===this.responseType?"[document data]":String(this.response||"")}catch(e){i="[unreadable response body]"}const r={timestamp:s,end_time:t,method:this._requestMethod,url:this._requestUrl,body:this._requestBody,status:this.status,request:{headers:this._requestHeaders||{},body:this._requestBody},response:{headers:n,body:i}};e.handleEvent(r)})),n.apply(this,t)}}patchFetch(){const e=globalThis.fetch;globalThis.fetch=(...t)=>{const n=Date.now();let[i,s]=t;s={...s||{}},t[1]=s;const r=s?.method||"GET",a=s?.body||"",o=i instanceof Request?i.url:i.toString();if(this.shouldIgnoreRequest(o))return e.apply(globalThis,t);const l=this.shouldAddTraceHeader(o);if(s||(t[1]={},s=t[1]),s.headers||(s.headers={}),l){const e=this.config.getConfig(),t=this.getTraceIds();e?.options?.traceOrigin?.name&&this.addHeaderToFetchRequest({init:s,headerName:e.options.traceOrigin.name,headerValue:e.options.traceOrigin.value}),t&&(e?.options?.tracePropagationTraceIdHeaderName&&this.addHeaderToFetchRequest({init:s,headerName:e.options.tracePropagationTraceIdHeaderName,headerValue:t.decimalTraceId}),e?.options?.tracePropagationSpanIdHeaderName&&this.addHeaderToFetchRequest({init:s,headerName:e.options.tracePropagationSpanIdHeaderName,headerValue:t.decimalSpanId}),e?.options?.tracePropagationHeaders?e.options.tracePropagationHeaders.forEach((e=>{this.addHeaderToFetchRequest({init:s,headerName:e,headerValue:t.traceparent})})):this.addHeaderToFetchRequest({init:s,headerName:"traceparent",headerValue:t.traceparent}))}const d={};return s?.headers&&(s.headers instanceof Headers?s.headers.forEach(((e,t)=>{d[t]=e})):"object"==typeof s.headers&&Object.assign(d,s.headers)),e.apply(globalThis,t).then((async e=>{const t=Date.now(),i=e.clone();let s="";const l={};i.headers.forEach(((e,t)=>{l[t]=e}));try{s=l["content-type"]?.includes("text/event-stream")?"[unreadable response body]":await this.getResponseBody(i)}catch(e){s="[unreadable response body]"}this.logger.log("[network-events-listener.patchFetch] called",{url:o});const c={method:r,url:o,timestamp:n,body:a.toString(),status:i.status,end_time:t,request:{headers:d,body:a.toString()},response:{headers:l,body:s}};return this.handleEvent(c),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:r,url:o,body:a.toString(),status:0,end_time:t,request:{headers:d,body:a.toString()},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]=L({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 R{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 I({type:"exception",attributes:{error_type:e.name||"Error",error_message:e.message||"Unknown error",error_stacktrace:this.buildStackTrace(e),error_fingerprint:`${e.name}:${L({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){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[]}}},x=class extends R{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 I({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)}}},P=class extends R{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 I({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)}}},M=class extends R{constructor(){super(...arguments),this.handleEvent=e=>{try{if(!E())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 I({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)}}},D=class{constructor(){this.logger=o.getInstance(),this.eventsPool=w.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=>{this.logger.log("[session-replay-listener] emit called",e),this.isRecording&&(this.events.push({type:e.type,data:e.data,timestamp:Date.now()}),this.events.length>=this.batchSize&&this.sendBatch())},recordCanvas:!0,collectFonts:!0,inlineStylesheet:!0,maskAllInputs:!0,maskInputOptions:{password:!0},slimDOMOptions:{script:!1,comment:!1,headFavicon:!1,headWhitespace:!1,headMetaDescKeywords:!1,headMetaSocial:!1,headMetaRobots:!1,headMetaHttpEquiv:!1,headMetaAuthorship:!1,headMetaVerification:!1},recordCrossOriginIframes:!1})||null,this.logger.log("[session-replay-listener] started recording")}catch(e){this.logger.log("[session-replay-listener] failed to start recording:",e)}}sendBatch(){if(0!==this.events.length)try{const e=[...this.events];this.events=[];const t=JSON.stringify(e),n=I({type:"replay",attributes:{replay_data:{events:btoa(t)}}});this.eventsPool.addEvent(n),this.logger.log("[session-replay-listener] sent batch with",e.length,"events")}catch(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){const t=JSON.stringify(this.events),n=I({type:"replay",attributes:{replay_data:{events:btoa(t)}}});this.eventsPool.addEvent(n),this.logger.log("[session-replay-listener] sent final replay event with",e,"events")}this.events=[],this.stopFn=null}catch(e){this.logger.log("[session-replay-listener] failed to stop recording:",e)}}destroy(){this.stopRecording()}},A=class{constructor(){this.logger=o.getInstance(),this.eventsPool=w.getInstance(),this.configManager=g.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 P,this.pageLoadListener.initialize(),i.push("pageload")),(n||t?.includes("dom"))&&(this.domEventsListener=new H,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")),(n||t?.includes("replay"))&&(this.sessionReplayListener=new D,this.sessionReplayListener.initialize(),i.push("replay")),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=I({type:"custom",attributes:{custom_event_name:e?.event,custom_event_attributes:e?.attributes}});this.eventsPool.addEvent(t)}catch(e){d(e)}}captureException(e){try{this.logger.log("[instrumentation-manager.captureException] called",e),this.errorsEventsListener?.handleEvent(e,{handled:!0})}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)}stopReplayRecording(){this.sessionReplayListener?this.sessionReplayListener.stopRecording():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()}},O="gcSample",U=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 A,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=g.getInstance();t.initialize(e);w.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(O);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(O,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");g.getInstance().updateConfig({userIdentifier:e})}updateConfig(e){if(!this.initialized)return void this.logger.log("[session-manager] cannot update config: SDK not initialized");g.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=w.getInstance();await t.flushSync();const n=e||this.idGenerator.generateId();g.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")}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 F={init:function(e){try{C=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){d(e)}},identifyUser:function(e){C?C.identifyUser(e):console.warn("[groundcover] identifyUser: groundcover is not initialized. please call init() first")},sendCustomEvent:function(e){C&&C.sendCustomEvent(e)},captureException:function(e){C&&C.captureException(e)},updateConfig:function(e){C&&C.updateConfig(e)},startNavigation:function(e){C?C.startNavigation(e):console.warn("[groundcover] startNavigation: groundcover is not initialized. please call init() first")},endNavigation:function(e){C?C.endNavigation(e):console.warn("[groundcover] endNavigation: groundcover is not initialized. please call init() first")},setSessionId:async function(e){if(C)try{await C.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")},stopReplayRecording:function(){C?C.stopReplayRecording():console.warn("[groundcover] stopReplayRecording: groundcover is not initialized. please call init() first")}};module.exports=F;
|
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 a,onTTFB as r,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 g(e){c.log("[error-handler.handleError] called",e,{groundcoverIgnore:!0})}var h={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={...h,...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:{},v=class{constructor(){this.generateTraceId=y(16),this.generateSpanId=y(8),this.generateId=y(16)}},f=Array(32);function y(e){return function(){for(let t=0;t<2*e;t++)f[t]=Math.floor(16*Math.random())+48,f[t]>=58&&(f[t]+=39);return String.fromCharCode.apply(null,f.slice(0,2*e))}}var E=p.getInstance(),b=new v;function I(){const e=E?.getConfig()?.options?.eventSampleRate;return!(void 0!==e&&!Number.isNaN(e))||Math.random()<=e}function N(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,N(i,s)):e[s]=i,e}),{})}function T(e){const t=1e6*Date.now(),n=b.generateId(),i=e.spanId||b.generateSpanId(),s=e.traceId||b.generateTraceId(),a=e.parentSpanId||"",r=N(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:a,traceId:s,attributes:{...r,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=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:a,isCompressed:r}=this.compress(s);fetch(i,{method:"POST",headers:{"Content-Type":"application/json",apikey:n,"Content-Encoding":r?"gzip":""},body:a}).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"],C=class e{constructor(){this.events=[],this.timeoutId=null,this.config=p.getInstance(),this.logger=d.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){g(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){g(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){g(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){g(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){g(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}}};C.instance=null;var L=C,H=class{constructor(){this.logger=d.getInstance(),this.eventsPool=L.getInstance()}};function q({text:e,maxLength:t=1e4}){return e?e.length<=t||"string"!=typeof e?e:e.substring(0,t):""}var z,R=class extends H{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?"*":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){g(e)}};this.eventHandlers.push({type:e,handler:t}),m?.addEventListener(e,t)}))}catch(e){g(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){g(e)}}buildEvent(e){const t=this.getSelector(e),n=this.getCoordinates(e),i=e.target,s=this.getKeyCode(e),a=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:a}}})}queueEvent(e){try{this.logger.log("[dom-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){g(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 a="",r=0,o=e;const l=[];for(;o&&o!==n&&o!==document.documentElement&&r<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||"*"),a=l.join(" > ");try{if(1===n.querySelectorAll(a).length)return a}catch(e){l.shift(),a=l.join(" > ")}try{o=o.parentElement}catch(e){break}r++}return a||"*"}},_=["log","info","warn","error","assert","trace"],k=class extends H{constructor(){super(...arguments),this.originalConsole=null,this.isInitialized=!1}initialize(){if(!this.isInitialized)try{this.originalConsole=this.captureConsoleMethods(),_.forEach((e=>{e in console&&(console[e]=(...t)=>{try{this.handleEvent(t,e)}catch(e){g(e)}finally{this.originalConsole?.[e]&&this.originalConsole[e](...t)}})})),this.isInitialized=!0}catch(e){g(e)}}destroy(){try{if(!this.isInitialized)return;_.forEach((e=>{this.originalConsole&&this.originalConsole[e]&&(console[e]=this.originalConsole[e])})),this.isInitialized=!1}catch(e){g(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){g(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){g(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 g(e),"[Error formatting console message]"}}captureConsoleMethods(){const e={};try{_.forEach((t=>{console&&"function"==typeof console[t]&&(e[t]=console[t].bind(console))}))}catch(e){g(e)}return e}},x=class extends H{constructor(){super(...arguments),this.maxBodyLength=5e3,this.config=p.getInstance(),this.idGenerator=new v,this.handleEvent=e=>{try{if(this.shouldIgnoreRequest(e.url))return;if(!I())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){g(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),a=e.method?.toUpperCase()||"UNKNOWN",{traceId:r,spanId:o}=this.extractTraceIds(e.request.headers),l={type:"HTTP",operation:{name:a},resource_name:t,status:e.status?.toString(),subType:a,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:q({text:e.request.body,maxLength:this.maxBodyLength})},response:{body:q({text:e.response.body,maxLength:this.maxBodyLength})}}},d={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:l};return r&&(d.traceId=r),o&&(d.spanId=o),T(d)}}async getResponseBody(e){let t;try{const n=e.clone().body;if(n){let e,i=n.getReader(),s=new TextDecoder,a="";for(;!(e=await i.read()).done;){let t=e.value;a+=s.decode(t)}t=a}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 g(e),!1}}queueEvent(e){try{this.logger.log("[network-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){g(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,a=!0,r,o){if(s=Date.now(),e.shouldIgnoreRequest(i.toString()))return t.apply(this,[n,i,a,r,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,a,r,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);const a=e.shouldAddTraceHeader(i);if(e.logger.log("[network-events-listener.patchXHR] test",{shouldAddTraceHeader:a}),a){const t=e.config.getConfig(),n=e.getTraceIds();e.logger.log("[network-events-listener.patchXHR] traceIds",{traceIds:n}),t?.options?.traceOrigin?.name&&e.addHeaderToXhrRequest({request:this,headerName:t.options.traceOrigin.name,headerValue:t.options.traceOrigin.value}),n&&(e.logger.log("[network-events-listener.patchXHR] traceIds",{traceIds:n,names:t?.options?.tracePropagationTraceIdHeaderName,spanIdHeaderName:t?.options?.tracePropagationSpanIdHeaderName,headers:t?.options?.tracePropagationHeaders}),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}),t?.options?.tracePropagationHeaders?t.options.tracePropagationHeaders.forEach((t=>{e.addHeaderToXhrRequest({request:this,headerName:t,headerValue:n.traceparent})})):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())}));let i="";try{i=""===this.responseType||"text"===this.responseType?this.responseText||"":"json"===this.responseType?JSON.stringify(this.response||""):"blob"===this.responseType?"[blob data]":"arraybuffer"===this.responseType?"[arraybuffer data]":"document"===this.responseType?"[document data]":String(this.response||"")}catch(e){i="[unreadable response body]"}const a={timestamp:s,end_time:t,method:this._requestMethod,url:this._requestUrl,body:this._requestBody,status:this.status,request:{headers:this._requestHeaders||{},body:this._requestBody},response:{headers:n,body:i}};e.handleEvent(a)})),n.apply(this,t)}}patchFetch(){const e=globalThis.fetch;globalThis.fetch=(...t)=>{const n=Date.now();let[i,s]=t;s={...s||{}},t[1]=s;const a=s?.method||"GET",r=s?.body||"",o=i instanceof Request?i.url:i.toString();if(this.shouldIgnoreRequest(o))return e.apply(globalThis,t);const l=this.shouldAddTraceHeader(o);if(s||(t[1]={},s=t[1]),s.headers||(s.headers={}),l){const e=this.config.getConfig(),t=this.getTraceIds();e?.options?.traceOrigin?.name&&this.addHeaderToFetchRequest({init:s,headerName:e.options.traceOrigin.name,headerValue:e.options.traceOrigin.value}),t&&(e?.options?.tracePropagationTraceIdHeaderName&&this.addHeaderToFetchRequest({init:s,headerName:e.options.tracePropagationTraceIdHeaderName,headerValue:t.decimalTraceId}),e?.options?.tracePropagationSpanIdHeaderName&&this.addHeaderToFetchRequest({init:s,headerName:e.options.tracePropagationSpanIdHeaderName,headerValue:t.decimalSpanId}),e?.options?.tracePropagationHeaders?e.options.tracePropagationHeaders.forEach((e=>{this.addHeaderToFetchRequest({init:s,headerName:e,headerValue:t.traceparent})})):this.addHeaderToFetchRequest({init:s,headerName:"traceparent",headerValue:t.traceparent}))}const d={};return s?.headers&&(s.headers instanceof Headers?s.headers.forEach(((e,t)=>{d[t]=e})):"object"==typeof s.headers&&Object.assign(d,s.headers)),e.apply(globalThis,t).then((async e=>{const t=Date.now(),i=e.clone();let s="";const l={};i.headers.forEach(((e,t)=>{l[t]=e}));try{s=l["content-type"]?.includes("text/event-stream")?"[unreadable response body]":await this.getResponseBody(i)}catch(e){s="[unreadable response body]"}this.logger.log("[network-events-listener.patchFetch] called",{url:o});const c={method:a,url:o,timestamp:n,body:r.toString(),status:i.status,end_time:t,request:{headers:d,body:r.toString()},response:{headers:l,body:s}};return this.handleEvent(c),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:o,body:r.toString(),status:0,end_time:t,request:{headers:d,body:r.toString()},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}},P=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){g(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 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}})}queueEvent(e){try{this.logger.log("[errors-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){g(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=m.location.href,this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState}catch(e){g(e)}}isInBrowserEnvironment(){try{return void 0!==m&&void 0!==m.location&&void 0!==m.history&&"function"==typeof m.addEventListener}catch(e){return g(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){g(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){g(e)}}handleEvent(){try{this.logger.log("[navigation-listener.handleEvent] called");const e=this.buildEvent();this.queueEvent(e)}catch(e){g(e)}}buildEvent(){this.logger.log("[navigation-listener.buildEvent] called",m.location.href);return T({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){g(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 g(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){g(e)}}},A=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",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),g(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){g(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,a=t.initiatorType;i.totalSize+=n,i.totalDuration+=s,i.byType[a]||(i.byType[a]={count:0,size:0,duration:0}),i.byType[a].count++,i.byType[a].size+=n,i.byType[a].duration+=s}));return T({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){g(e)}}},D=class extends H{constructor(){super(...arguments),this.handleEvent=e=>{try{if(!I())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){g(e)}}}initialize(){i(this.handleEvent),s(this.handleEvent),a(this.handleEvent),r(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){g(e)}}},U=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 A,this.pageLoadListener.initialize(),i.push("pageload")),(n||t?.includes("dom"))&&(this.domEventsListener=new R,this.domEventsListener.initialize(),i.push("dom")),(n||t?.includes("logs"))&&(this.logEventsListener=new k,this.logEventsListener.initialize(),i.push("logs")),(n||t?.includes("exceptions"))&&(this.errorsEventsListener=new P,this.errorsEventsListener.initialize(),i.push("exceptions")),(n||t?.includes("network"))&&(this.networkEventsListener=new x,this.networkEventsListener.initialize(),i.push("network")),(n||t?.includes("performance"))&&(this.performanceListener=new D,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){g(e)}}captureException(e){try{this.logger.log("[instrumentation-manager.captureException] called",e),this.errorsEventsListener?.handleEvent(e,{handled:!0})}catch(e){g(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()}},O="gcSample",j=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 U,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=p.getInstance();t.initialize(e);L.getInstance().initialize();t.getSessionId()||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(O);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(O,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 X={init:function(e){try{z=new j({cluster:e?.cluster||"",environment:e?.environment||"",namespace:e?.namespace,dsn:e?.dsn||"",appId:e?.appId||"",userIdentifier:e?.userIdentifier,apiKey:e?.apiKey||"",options:e?.options})}catch(e){g(e)}},identifyUser:function(e){z?z.identifyUser(e):console.warn("[groundcover] identifyUser: groundcover is not initialized. please call init() first")},sendCustomEvent:function(e){z&&z.sendCustomEvent(e)},captureException:function(e){z&&z.captureException(e)},updateConfig:function(e){z&&z.updateConfig(e)},startNavigation:function(e){z?z.startNavigation(e):console.warn("[groundcover] startNavigation: groundcover is not initialized. please call init() first")},endNavigation:function(e){z?z.endNavigation(e):console.warn("[groundcover] endNavigation: groundcover is not initialized. please call init() first")},setSessionId:async function(e){if(z)try{await z.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")}};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 a,onTTFB as r,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}},h=c.getInstance();function g(e){h.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")}},v="object"==typeof globalThis?globalThis:"object"==typeof self?self:"object"==typeof window?window:"object"==typeof global?global:{},f=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 f;function N(){const e=b?.getConfig()?.options?.eventSampleRate;return!(void 0!==e&&!Number.isNaN(e))||Math.random()<=e}function S(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,S(i,s)):e[s]=i,e}),{})}function T(e){const t=1e6*Date.now(),n=I.generateId(),i=e.spanId||I.generateSpanId(),s=e.traceId||I.generateTraceId(),a=e.parentSpanId||"",r=S(e.attributes||{}),o=function(){const e=v?.location;return e?{path:e.hash&&!e.hash.match(/^#[a-z0-9-]+$/i)&&e.hash.startsWith("#/")?e.hash:e.pathname,url:e.href,title:v?.document?.title||""}:{path:"",url:"",title:v?.document?.title||""}}(),l={type:e.type,id:n,spanId:i,parentSpanId:a,traceId:s,attributes:{...r,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 w=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:a,isCompressed:r}=this.compress(s);fetch(i,{method:"POST",headers:{"Content-Type":"application/json",apikey:n,"Content-Encoding":r?"gzip":""},body:a}).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`}},R=["navigation","dom.event"],L=class e{constructor(){this.events=[],this.timeoutId=null,this.config=m.getInstance(),this.logger=c.getInstance(),this.initialized=!1,this.transporter=new w}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){g(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&&!R.includes(e.type)&&this.flush()}catch(e){g(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){g(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){g(e)}}scheduleFlush(){try{null!==this.timeoutId&&(v.clearTimeout(this.timeoutId),this.timeoutId=null);const e=this.config.getConfig()?.options?.batchTimeout;if(!e)return;this.timeoutId=v.setTimeout((()=>{this.timeoutId=null,this.flush()}),e)}catch(e){g(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}}};L.instance=null;var C=L,H=class{constructor(){this.logger=c.getInstance(),this.eventsPool=C.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 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?"*":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){g(e)}};this.eventHandlers.push({type:e,handler:t}),v?.addEventListener(e,t)}))}catch(e){g(e)}}destroy(){this.eventHandlers.forEach((({type:e,handler:t})=>{global?.removeEventListener?.(e,t)})),this.eventHandlers=[]}handleEvent(e){try{if(!N())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){g(e)}}buildEvent(e){const t=this.getSelector(e),n=this.getCoordinates(e),i=e.target,s=this.getKeyCode(e),a=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:a}}})}queueEvent(e){try{this.logger.log("[dom-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){g(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 a="",r=0,o=e;const l=[];for(;o&&o!==n&&o!==document.documentElement&&r<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||"*"),a=l.join(" > ");try{if(1===n.querySelectorAll(a).length)return a}catch(e){l.shift(),a=l.join(" > ")}try{o=o.parentElement}catch(e){break}r++}return a||"*"}},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){g(e)}finally{this.originalConsole?.[e]&&this.originalConsole[e](...t)}})})),this.isInitialized=!0}catch(e){g(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){g(e)}}handleEvent(e,t){try{if(!N())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){g(e)}}buildEvent({message:e,level:t}){return T({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){g(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 g(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){g(e)}return e}},P=class extends H{constructor(){super(...arguments),this.maxBodyLength=5e3,this.config=m.getInstance(),this.idGenerator=new f,this.handleEvent=e=>{try{if(this.shouldIgnoreRequest(e.url))return;if(!N())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){g(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),a=e.method?.toUpperCase()||"UNKNOWN",{traceId:r,spanId:o}=this.extractTraceIds(e.request.headers),l={type:"HTTP",operation:{name:a},resource_name:t,status:e.status?.toString(),subType:a,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:z({text:e.request.body,maxLength:this.maxBodyLength})},response:{body:z({text:e.response.body,maxLength:this.maxBodyLength})}}},d={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:l};return r&&(d.traceId=r),o&&(d.spanId=o),T(d)}}async getResponseBody(e){let t;try{const n=e.clone().body;if(n){let e,i=n.getReader(),s=new TextDecoder,a="";for(;!(e=await i.read()).done;){let t=e.value;a+=s.decode(t)}t=a}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 g(e),!1}}queueEvent(e){try{this.logger.log("[network-events-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){g(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,a=!0,r,o){if(s=Date.now(),e.shouldIgnoreRequest(i.toString()))return t.apply(this,[n,i,a,r,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,a,r,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);const a=e.shouldAddTraceHeader(i);if(e.logger.log("[network-events-listener.patchXHR] test",{shouldAddTraceHeader:a}),a){const t=e.config.getConfig(),n=e.getTraceIds();e.logger.log("[network-events-listener.patchXHR] traceIds",{traceIds:n}),t?.options?.traceOrigin?.name&&e.addHeaderToXhrRequest({request:this,headerName:t.options.traceOrigin.name,headerValue:t.options.traceOrigin.value}),n&&(e.logger.log("[network-events-listener.patchXHR] traceIds",{traceIds:n,names:t?.options?.tracePropagationTraceIdHeaderName,spanIdHeaderName:t?.options?.tracePropagationSpanIdHeaderName,headers:t?.options?.tracePropagationHeaders}),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}),t?.options?.tracePropagationHeaders?t.options.tracePropagationHeaders.forEach((t=>{e.addHeaderToXhrRequest({request:this,headerName:t,headerValue:n.traceparent})})):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())}));let i="";try{i=""===this.responseType||"text"===this.responseType?this.responseText||"":"json"===this.responseType?JSON.stringify(this.response||""):"blob"===this.responseType?"[blob data]":"arraybuffer"===this.responseType?"[arraybuffer data]":"document"===this.responseType?"[document data]":String(this.response||"")}catch(e){i="[unreadable response body]"}const a={timestamp:s,end_time:t,method:this._requestMethod,url:this._requestUrl,body:this._requestBody,status:this.status,request:{headers:this._requestHeaders||{},body:this._requestBody},response:{headers:n,body:i}};e.handleEvent(a)})),n.apply(this,t)}}patchFetch(){const e=globalThis.fetch;globalThis.fetch=(...t)=>{const n=Date.now();let[i,s]=t;s={...s||{}},t[1]=s;const a=s?.method||"GET",r=s?.body||"",o=i instanceof Request?i.url:i.toString();if(this.shouldIgnoreRequest(o))return e.apply(globalThis,t);const l=this.shouldAddTraceHeader(o);if(s||(t[1]={},s=t[1]),s.headers||(s.headers={}),l){const e=this.config.getConfig(),t=this.getTraceIds();e?.options?.traceOrigin?.name&&this.addHeaderToFetchRequest({init:s,headerName:e.options.traceOrigin.name,headerValue:e.options.traceOrigin.value}),t&&(e?.options?.tracePropagationTraceIdHeaderName&&this.addHeaderToFetchRequest({init:s,headerName:e.options.tracePropagationTraceIdHeaderName,headerValue:t.decimalTraceId}),e?.options?.tracePropagationSpanIdHeaderName&&this.addHeaderToFetchRequest({init:s,headerName:e.options.tracePropagationSpanIdHeaderName,headerValue:t.decimalSpanId}),e?.options?.tracePropagationHeaders?e.options.tracePropagationHeaders.forEach((e=>{this.addHeaderToFetchRequest({init:s,headerName:e,headerValue:t.traceparent})})):this.addHeaderToFetchRequest({init:s,headerName:"traceparent",headerValue:t.traceparent}))}const d={};return s?.headers&&(s.headers instanceof Headers?s.headers.forEach(((e,t)=>{d[t]=e})):"object"==typeof s.headers&&Object.assign(d,s.headers)),e.apply(globalThis,t).then((async e=>{const t=Date.now(),i=e.clone();let s="";const l={};i.headers.forEach(((e,t)=>{l[t]=e}));try{s=l["content-type"]?.includes("text/event-stream")?"[unreadable response body]":await this.getResponseBody(i)}catch(e){s="[unreadable response body]"}this.logger.log("[network-events-listener.patchFetch] called",{url:o});const c={method:a,url:o,timestamp:n,body:r.toString(),status:i.status,end_time:t,request:{headers:d,body:r.toString()},response:{headers:l,body:s}};return this.handleEvent(c),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:o,body:r.toString(),status:0,end_time:t,request:{headers:d,body:r.toString()},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}},M=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){g(e)}}}initialize(){v?.addEventListener("error",this.handleEvent),v?.addEventListener("unhandledrejection",this.handleEvent)}destroy(){v?.removeEventListener("error",this.handleEvent),v?.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}:${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){g(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[]}}},D=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=v.location.href,this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState}catch(e){g(e)}}isInBrowserEnvironment(){try{return void 0!==v&&void 0!==v.location&&void 0!==v.history&&"function"==typeof v.addEventListener}catch(e){return g(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},v&&"function"==typeof v.addEventListener&&(v.addEventListener("popstate",this.popStateHandler),v.addEventListener("hashchange",this.hashChangeHandler)),this.isInitialized=!0}catch(e){g(e)}}destroy(){try{this.logger.log("[navigation-listener.destroy] called"),this.isInitialized&&this.originalPushState&&this.originalReplaceState&&(history.pushState=this.originalPushState,history.replaceState=this.originalReplaceState),v&&"function"==typeof v.removeEventListener&&(v.removeEventListener("popstate",this.popStateHandler),v.removeEventListener("hashchange",this.hashChangeHandler)),this.isInitialized=!1}catch(e){g(e)}}handleEvent(){try{this.logger.log("[navigation-listener.handleEvent] called");const e=this.buildEvent();this.queueEvent(e)}catch(e){g(e)}}buildEvent(){this.logger.log("[navigation-listener.buildEvent] called",v.location.href);return T({type:"navigation",attributes:{page_url:v.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){g(e)}}startNavigation(e){this.logger.log("[navigation-listener.startNavigation] called",e),this.activeNavigation={page_url:v.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===v.location.href)return;let e,t;try{e=new URL(v.location.href),t=new URL(this.currentUrl)}catch(e){return void g(e)}const n=e=>e.startsWith("#/"),i=n(e.hash)||n(t.hash);(e.pathname!==t.pathname||i&&e.hash!==t.hash)&&(this.currentUrl=v.location.href,this.handleEvent())}catch(e){g(e)}}},A=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",v),"complete"===v?.document?.readyState?(this.logger.log("Page already loaded, triggering event immediately"),this.handleEvent()):v?.addEventListener("load",this.loadEventHandler)}catch(e){this.logger.log("[page-load-listener.initialize] error",e),g(e)}}destroy(){v?.removeEventListener("load",this.loadEventHandler)}handleEvent(){try{this.logger.log("[page-load-listener.handleEvent] called");const e=this.buildEvent();this.queueEvent(e)}catch(e){g(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,a=t.initiatorType;i.totalSize+=n,i.totalDuration+=s,i.byType[a]||(i.byType[a]={count:0,size:0,duration:0}),i.byType[a].count++,i.byType[a].size+=n,i.byType[a].duration+=s}));return T({type:"pageload",attributes:{page_url:v?.location?.href||"",page_load_time:t,page_referrer:v?.document?.referrer||"",page_resources:i}})}queueEvent(e){try{this.logger.log("[page-load-listener.queueEvent] called"),e&&this.eventsPool.addEvent(e)}catch(e){g(e)}}},O=class extends H{constructor(){super(...arguments),this.handleEvent=e=>{try{if(!N())return;const t=this.buildEvent(e);this.queueEvent(t)}catch(e){g(e)}}}initialize(){i(this.handleEvent),s(this.handleEvent),a(this.handleEvent),r(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){g(e)}}},U=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=>{this.logger.log("[session-replay-listener] emit called",e),this.isRecording&&(this.events.push({type:e.type,data:e.data,timestamp:Date.now()}),this.events.length>=this.batchSize&&this.sendBatch())},recordCanvas:!0,collectFonts:!0,inlineStylesheet:!0,maskAllInputs:!0,maskInputOptions:{password:!0},slimDOMOptions:{script:!1,comment:!1,headFavicon:!1,headWhitespace:!1,headMetaDescKeywords:!1,headMetaSocial:!1,headMetaRobots:!1,headMetaHttpEquiv:!1,headMetaAuthorship:!1,headMetaVerification:!1},recordCrossOriginIframes:!1})||null,this.logger.log("[session-replay-listener] started recording")}catch(e){this.logger.log("[session-replay-listener] failed to start recording:",e)}}sendBatch(){if(0!==this.events.length)try{const e=[...this.events];this.events=[];const t=JSON.stringify(e),n=T({type:"replay",attributes:{replay_data:{events:btoa(t)}}});this.eventsPool.addEvent(n),this.logger.log("[session-replay-listener] sent batch with",e.length,"events")}catch(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){const t=JSON.stringify(this.events),n=T({type:"replay",attributes:{replay_data:{events:btoa(t)}}});this.eventsPool.addEvent(n),this.logger.log("[session-replay-listener] sent final replay event with",e,"events")}this.events=[],this.stopFn=null}catch(e){this.logger.log("[session-replay-listener] failed to stop recording:",e)}}destroy(){this.stopRecording()}},j=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 A,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 M,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 O,this.performanceListener.initialize(),i.push("performance")),(n||t?.includes("replay"))&&(this.sessionReplayListener=new U,this.sessionReplayListener.initialize(),i.push("replay")),this.navigationListener=new D({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){g(e)}}captureException(e){try{this.logger.log("[instrumentation-manager.captureException] called",e),this.errorsEventsListener?.handleEvent(e,{handled:!0})}catch(e){g(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)}stopReplayRecording(){this.sessionReplayListener?this.sessionReplayListener.stopRecording():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",X=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 j,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=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(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");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){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=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")}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 $={init:function(e){try{q=new X({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){g(e)}},identifyUser:function(e){q?q.identifyUser(e):console.warn("[groundcover] identifyUser: groundcover is not initialized. please call init() first")},sendCustomEvent:function(e){q&&q.sendCustomEvent(e)},captureException:function(e){q&&q.captureException(e)},updateConfig:function(e){q&&q.updateConfig(e)},startNavigation:function(e){q?q.startNavigation(e):console.warn("[groundcover] startNavigation: groundcover is not initialized. please call init() first")},endNavigation:function(e){q?q.endNavigation(e):console.warn("[groundcover] endNavigation: groundcover is not initialized. please call init() first")},setSessionId:async function(e){if(q)try{await q.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")},stopReplayRecording:function(){q?q.stopReplayRecording():console.warn("[groundcover] stopReplayRecording: groundcover is not initialized. please call init() first")}};export{$ as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@groundcover/browser",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.53-dev.0",
|
|
4
4
|
"description": "groundcover browser SDK",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -18,12 +18,21 @@
|
|
|
18
18
|
"README.md",
|
|
19
19
|
"LICENSE"
|
|
20
20
|
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build:watch": "tsc --noEmit && WATCH=true tsup --watch",
|
|
23
|
+
"build": "tsc --noEmit && tsup",
|
|
24
|
+
"size": "npm run build && size-limit",
|
|
25
|
+
"lint": "eslint .",
|
|
26
|
+
"test": "vitest && npm run lint && npm run size",
|
|
27
|
+
"prepublish": "pnpm run build"
|
|
28
|
+
},
|
|
21
29
|
"keywords": [
|
|
22
30
|
"rum",
|
|
23
31
|
"sdk"
|
|
24
32
|
],
|
|
25
33
|
"author": "groundcover",
|
|
26
34
|
"license": "MIT",
|
|
35
|
+
"packageManager": "pnpm@9.15.0+sha512.76e2379760a4328ec4415815bcd6628dee727af3779aaa4c914e3944156c4299921a89f976381ee107d41f12cfa4b66681ca9c718f0668fa0831ed4c6d8ba56c",
|
|
27
36
|
"devDependencies": {
|
|
28
37
|
"@eslint/js": "^9.19.0",
|
|
29
38
|
"@size-limit/preset-big-lib": "^11.2.0",
|
|
@@ -42,6 +51,7 @@
|
|
|
42
51
|
"dependencies": {
|
|
43
52
|
"error-stack-parser": "^2.1.4",
|
|
44
53
|
"fflate": "^0.8.2",
|
|
54
|
+
"rrweb": "^2.0.0-alpha.18",
|
|
45
55
|
"web-vitals": "^4.2.4"
|
|
46
56
|
},
|
|
47
57
|
"size-limit": [
|
|
@@ -53,13 +63,5 @@
|
|
|
53
63
|
"path": "dist/index.mjs",
|
|
54
64
|
"limit": "30 kB"
|
|
55
65
|
}
|
|
56
|
-
]
|
|
57
|
-
|
|
58
|
-
"build:watch": "tsc --noEmit && WATCH=true tsup --watch",
|
|
59
|
-
"build": "tsc --noEmit && tsup",
|
|
60
|
-
"size": "npm run build && size-limit",
|
|
61
|
-
"lint": "eslint .",
|
|
62
|
-
"test": "vitest && npm run lint && npm run size",
|
|
63
|
-
"prepublish": "pnpm run build"
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
+
]
|
|
67
|
+
}
|